วิธีการแปลง java.util.Date เป็น java.sql.Date?


453

ฉันพยายามที่จะใช้java.util.Dateเป็นอินพุตแล้วสร้างแบบสอบถามด้วย - ดังนั้นฉันต้องการjava.sql.Dateดังนั้นฉันต้องการ

ฉันประหลาดใจที่พบว่ามันไม่สามารถทำการแปลงได้โดยปริยายหรืออย่างชัดเจน - แต่ฉันไม่รู้ด้วยซ้ำว่าฉันจะทำสิ่งนี้อย่างไรเนื่องจาก Java API ยังค่อนข้างใหม่สำหรับฉัน


คุณสามารถค้นหาปัญหาที่คล้ายกันได้ที่นี่ stackoverflow.com/questions/12131068/…
Lem

สำหรับฉันมันกลายเป็นว่าฉันไม่ต้องการแปลง มีอยู่import java.sql.*ในรหัสของฉันแทนที่ java.util.date และทำให้เกิดปัญหาเมื่อกำหนดค่าวันที่ซึ่งดีกับหลัง แต่ไม่ใช่คนแรก HTH
HumanInDisguise

1
@DavidAckerman คุณเข้าใจหรือไม่ว่า java.util.Date เป็นวันที่และเวลาของวัน แต่ java.sql.Date เป็นเพียงวันที่ที่ไม่มีเวลาวันหรือไม่ (อันที่จริงมีเวลาของวัน แต่ที่ถูกละเว้นแฮ็คที่ไม่ดีของการออกแบบคลาส) ใน SQL DATEหมายถึงวันที่เท่านั้น
Basil Bourque

2
ฉันไม่ทราบถึงความแตกต่างในปี '09 และเนื่องจากคำถามนี้เป็นที่นิยมมากฉันจึงเปลี่ยนคำตอบที่ยอมรับเป็นคำตอบที่ทั้งทันสมัยและสมบูรณ์ยิ่งขึ้น ขอบคุณทุกคนสำหรับการป้อนข้อมูลของคุณ!
David Ackerman

คำตอบ:


89

TL; DR

วิธีการแปลง java.util.Date เป็น java.sql.Date?

อย่า ทั้งสองคลาสนั้นล้าสมัย

  • ใช้คลาสjava.timeแทนแบบดั้งเดิมjava.util.Date& java.sql.Dateกับ JDBC 4.2 หรือใหม่กว่า
  • แปลงเป็น / จาก java.time หากการปฏิบัติการระหว่างกันกับรหัสยังไม่ได้รับการอัพเดตเป็น java.time

PreparedStatementตัวอย่างแบบสอบถาม

myPreparedStatement.setObject( 
     ,                                         // Specify the ordinal number of which argument in SQL statement.
    myJavaUtilDate.toInstant()                  // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
        .atZone( ZoneId.of( "Africa/Tunis" ) )  // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
        .toLocalDate()                          // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)

เปลี่ยน:

  • Instantแทนที่จะเป็นjava.util.Date
    ทั้งสองแทนช่วงเวลาใน UTC แต่ตอนนี้มีนาโนวินาทีแทนที่จะเป็นมิลลิวินาที
  • LocalDateแทนที่จะเป็นjava.sql.Date
    ทั้งสองแทนค่าวันที่เท่านั้นโดยไม่มีเวลาของวันและไม่มีเขตเวลา

รายละเอียด

ถ้าคุณกำลังพยายามที่จะทำงานร่วมกับค่าวันเท่านั้น (ไม่มีเวลาของวันไม่มีโซนเวลา) ให้ใช้ระดับมากกว่าLocalDatejava.util.Date

ตารางประเภทวันที่ - เวลาใน Java (ทั้งแบบดั้งเดิมและสมัยใหม่) และในมาตรฐาน SQL

java.time

ใน Java 8 และต่อมาลำบากเก่าชั้นเรียนวันที่เวลาที่มาพร้อมกับรุ่นแรกของ Java ได้รับการแทนที่ด้วยใหม่แพคเกจ java.time ดูออราเคิลกวดวิชา ฟังก์ชั่นส่วนใหญ่ได้รับการแบ็คอัพไปยัง Java 6 และ 7 ในThreeTen-Backportและปรับใช้กับ Android ในThreeTenABPเพิ่มเติม

ชนิดข้อมูล SQL DATEมีขึ้นเพื่อเป็นวันเดียวกับไม่มีเวลาของวันและโซนเวลาไม่นาน Java ไม่เคยมีคลาสดังกล่าวอย่างแม่นยำ precisely จนกระทั่งjava.time.LocalDateใน Java 8 เรามาสร้างคุณค่าโดยรับวันที่วันนี้ตามเขตเวลาเฉพาะ (เขตเวลามีความสำคัญในการกำหนดวันที่เป็นรุ่งอรุณของวันใหม่ในปารีสกว่าMontréalสำหรับ ตัวอย่าง).

LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );  // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".

ณ จุดนี้เราอาจจะทำ หากไดรเวอร์ JDBCของคุณเป็นไปตามข้อกำหนดJDBC 4.2คุณควรจะสามารถส่งLocalDateผ่านsetObjectบนPreparedStatementเพื่อเก็บลงในฟิลด์ SQL DATE

myPreparedStatement.setObject( 1 , localDate );

เช่นเดียวกันใช้ResultSet::getObjectเพื่อดึงข้อมูลจากคอลัมน์ SQL DATE ไปยังLocalDateวัตถุJava ระบุระดับในการโต้เถียงที่สองทำให้รหัสของคุณชนิดปลอดภัย

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

ในคำอื่น ๆคำถามทั้งหมดนี้ไม่เกี่ยวข้องภายใต้ JDBC 4.2หรือในภายหลัง

หากไดรเวอร์ JDBC ของคุณไม่ทำงานในลักษณะนี้คุณต้องถอยกลับไปที่การแปลงเป็นประเภท java.sql

แปลงเป็น java.sql.Date

ในการแปลงให้ใช้วิธีการใหม่ที่เพิ่มเข้ามาในคลาสวันที่เก่า เราสามารถเรียกการแปลงjava.sql.Date.valueOf(…)LocalDate

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

และไปในทิศทางอื่น

LocalDate localDate = sqlDate.toLocalDate();

แปลงจาก java.util.Date

แม้ว่าคุณควรหลีกเลี่ยงการใช้คลาสวันที่เก่า แต่คุณอาจถูกบังคับให้ทำงานกับรหัสที่มีอยู่ ถ้าเป็นเช่นนั้นคุณสามารถแปลงเป็น / จาก java.time

ผ่านInstantชั้นเรียนซึ่งแสดงถึงช่วงเวลาในเส้นเวลาใน UTC จะคล้ายกันในความคิดไปInstant java.util.Dateแต่โปรดทราบว่าInstantมีความละเอียดสูงถึงนาโนวินาทีในขณะที่java.util.Dateมีเพียงมิลลิวินาทีเท่านั้นความละเอียดเป็น

ในการแปลงให้ใช้วิธีการใหม่ที่เพิ่มในคลาสเก่า ยกตัวอย่างเช่นและjava.util.Date.from( Instant )java.util.Date::toInstant

Instant instant = myUtilDate.toInstant();

ในการกำหนดวันที่เราต้องการบริบทของเขตเวลา สำหรับช่วงเวลาใด ๆ วันที่จะแตกต่างกันไปทั่วโลกตามโซนเวลา ใช้ a ZoneIdเพื่อรับ a ZonedDateTime.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

java คลาส java.sql วันที่อ้างว่าเป็นวันที่เท่านั้นโดยไม่มีเวลาของวัน แต่จริง ๆ แล้วทำเวลาของวันปรับเป็นเวลาเที่ยงคืน ทำให้เกิดความสับสน? ใช่คลาสวันที่แบบเก่านั้นไม่เป็นระเบียบ


เกี่ยวกับjava.time

java.timeกรอบถูกสร้างขึ้นใน Java 8 และต่อมา ชั้นเรียนเหล่านี้แย่งลำบากเก่ามรดกเรียนวันที่เวลาเช่นjava.util.Date, CalendarและSimpleDateFormatและ

Joda เวลาโครงการขณะนี้อยู่ในโหมดการบำรุงรักษาให้คำแนะนำแก่การโยกย้ายไปยังjava.timeชั้นเรียน

ต้องการเรียนรู้เพิ่มเติมโปรดดูที่ออราเคิลกวดวิชา และค้นหา Stack Overflow สำหรับตัวอย่างและคำอธิบายมากมาย สเปกJSR 310

คุณสามารถแลกเปลี่ยนวัตถุjava.timeโดยตรงกับฐานข้อมูลของคุณ ใช้ไดรเวอร์ JDBC ที่สอดคล้องกับJDBC 4.2หรือใหม่กว่า ไม่จำเป็นต้องใช้สตริงไม่จำเป็นต้องมีjava.sql.*คลาส

จะรับคลาส java.time ได้ที่ไหน?

  • Java SE 8 , Java SE 9 , Java SE 10และใหม่กว่า
    • Built-in
    • เป็นส่วนหนึ่งของ Java API มาตรฐานที่มีการใช้งานแบบรวม
    • Java 9 เพิ่มคุณสมบัติและการแก้ไขเล็กน้อย
  • Java SE 6และ Java SE 7
    • มากของการทำงาน java.time จะกลับรังเพลิง Java 6 และ 7 ในThreeTen-ย้ายกลับ
  • Android

ตารางที่ไลบรารี java.time ใดที่จะใช้กับเวอร์ชันของ Java หรือ Android

โครงการThreeTen-Extraขยาย java.time ด้วยคลาสเพิ่มเติม โครงการนี้เป็นพื้นฐานที่พิสูจน์ได้สำหรับการเพิ่มเติมในอนาคตไปยัง java.time คุณอาจพบว่าการเรียนที่มีประโยชน์บางอย่างที่นี่เช่นInterval, YearWeek, YearQuarterและอื่น ๆ อีกมากมาย


478

ไม่เป็นไร....

public class MainClass {

  public static void main(String[] args) {
    java.util.Date utilDate = new java.util.Date();
    java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    System.out.println("utilDate:" + utilDate);
    System.out.println("sqlDate:" + sqlDate);

  }

}

อธิบายมัน ลิงก์คือhttp://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm


34
นี่ไม่ใช่การแปลงที่ชัดเจน! จาก Javadoc: "ถ้าค่ามิลลิวินาทีที่ระบุมีข้อมูลเวลาไดรเวอร์จะตั้งค่าคอมโพเนนต์เวลาเป็นเวลาในโซนเวลาเริ่มต้น (โซนเวลาของเครื่องเสมือน Java ที่รันแอปพลิเคชัน) ที่สอดคล้องกับศูนย์ GMT" ดังนั้นไม่ว่าเวลาของคุณบน java.util.Date ของคุณจะถูกแทรกเป็น 00:00:00 ในคอลัมน์ที่ตั้งค่าชนิดข้อมูลเป็น DATE

1
@ David Ackerman ..... วิธีการนี้จะส่งกลับมิลลิวินาทีคือหลังจากepochseconds 1,JAN,1970แต่ถ้าเราต้องการเก็บวันที่ของคนก่อนวันที่นี้ .... หรืออะไรทำนองนั้น0000-00-00 as default
Arjun KP

31
ในกรณีของฉันคำตอบที่ถูกต้องคือ <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code> เพราะมันรักษาเขตเวลา
Alberto de Paola

2
@ wired00 ใช่คลาสวันที่และเวลาเก่าที่มาพร้อมกับ Java เวอร์ชันแรกนั้นมีความยุ่งเหยิงออกแบบมาไม่ดีรวมถึงแฮ็คที่หยาบ เมื่อใดก็ตามที่เป็นไปได้ให้ลองใช้เฟรมเวิร์ก java.timeใหม่ใน Java 8 และใหม่กว่า คลาสใหม่เหล่านี้แทนที่เก่า คลาส java.time และคลาสเก่ามีวิธีอำนวยความสะดวกบางอย่างสำหรับการแปลงไปมา - มีประโยชน์ในขณะที่เรารอให้ไดรเวอร์ JDBC ได้รับการอัปเดตเพื่อใช้ประเภท java.time ใหม่โดยตรง
Basil Bourque

1
@ wired00 ดูคำตอบใหม่ของฉันสำหรับคำถามนี้สำหรับวิธีการใช้ java.time ค้นหา StackOverflow สำหรับตัวอย่างอื่น ๆ อีกมากมาย
Basil Bourque

39

ด้วยคำตอบอื่นคุณอาจมีปัญหากับข้อมูลเวลา (เปรียบเทียบวันที่กับผลลัพธ์ที่ไม่คาดคิด!)

ฉันแนะนำ:

java.util.Calendar cal = Calendar.getInstance();
java.util.Date utilDate = new java.util.Date(); // your util date
cal.setTime(utilDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);    
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime()); // your sql date
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);

5
หากเขาใช้ java.sql.Date สำหรับคอลัมน์ Date ในฐานข้อมูลข้อมูลเวลานั้นจะถูกตัดทอน คุณได้ยกเลิกความคิดของฉันไปแล้ว
darioo

4
ใช่ฉันอาจจะทำมัน บางครั้งฉันต้องเปรียบเทียบ java.sql.Data กับวันที่ปัจจุบันและ imho นี่เป็นวิธีที่ดีที่สุด ฉันหวังว่ามันจะช่วยได้
mauretto

FYI, ลำบากชะมัดเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และต่อมา ดูการสอนโดยออราเคิล
Basil Bourque

แน่นอนหัวข้อนี้เป็นเวลาประมาณ 10 ปีที่ผ่านมา pre-java 8
mauretto

26

ฟังก์ชั่นนี้จะคืนค่าวันที่แปลง SQL จากวัตถุวันที่จาวา

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}

18

การแปลงjava.util.Dataเป็นjava.sql.Dataชั่วโมงชั่วโมงนาทีและวินาทีที่หลวม ดังนั้นถ้าเป็นไปได้ฉันขอแนะนำให้คุณใช้java.sql.Timestampดังนี้:

prepareStatement.setTimestamp(1, new Timestamp(utilDate.getTime()));

สำหรับข้อมูลเพิ่มเติมคุณสามารถตรวจสอบคำถามนี้


16

ในกรณีของฉันในการเลือกวันที่จาก JXDatePicker (ปฏิทิน java) และทำให้มันถูกเก็บไว้ในฐานข้อมูลเป็นชนิด SQL Date ด้านล่างใช้งานได้ดี ..

java.sql.Date date = new java.sql.Date(pickedDate.getDate().getTime());

โดยที่ PickDate เป็นวัตถุของ JXDatePicker


5

ฟังก์ชั่นนี้จะคืนค่าวันที่แปลง SQL จากวัตถุวันที่จาวา

public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }

3

จัดรูปแบบ java.util.Date ของคุณก่อน จากนั้นใช้วันที่จัดรูปแบบเพื่อรับวันที่ใน java.sql.Date

java.util.Date utilDate = "Your date"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String stringDate= dateFormat.format(utilDate);
final java.sql.Date sqlDate=  java.sql.Date.valueOf(stringDate);

2

นี่คือตัวอย่างของการแปลง Util Date เป็น Date sql และ ya นี่เป็นตัวอย่างหนึ่งที่ฉันใช้ในโครงการของฉันอาจเป็นประโยชน์กับคุณเช่นกัน

java.util.Date utilStartDate = table_Login.getDob();(orwhat ever date your give form obj)
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());(converting date)

2

ฉันเป็นสามเณรหลังจากทำงานนี้มานาน ความคิดอาจมีประโยชน์

     String bufDt =  bDOB.getText();  //data from form
     DateFormat dF = new SimpleDateFormat("dd-MM-yyyy"); //data in form is in this format
     Date bbdt = (Date)dF.parse(bufDt);  // string data is converted into java util date
     DateFormat dsF = new SimpleDateFormat("yyyy-MM-dd"); //converted date is reformatted for conversion to sql.date
     String ndt = dsF.format(bbdt); // java util date is converted to compatible java sql date
     java.sql.Date sqlDate=  java.sql.Date.valueOf(ndt);  // finally data from the form is convered to java sql. date for placing in database

FYI, ลำบากชะมัดเก่าชั้นเรียนวันที่เวลาเช่นjava.util.Date, java.util.Calendarและjava.text.SimpleDateFormatตอนนี้มรดกแทนที่โดยjava.timeชั้นเรียนที่สร้างขึ้นใน Java 8 และต่อมา ดูการสอนโดยออราเคิล
Basil Bourque

2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

javaDate นี่เป็นตัวอย่างของ java.util.Date


1
ดูเหมือนว่าจะไม่เพิ่มอะไรใหม่เมื่อเทียบกับคำตอบของ David Ackerman, chetan และ Tanmay kumar Shaw ใช่ไหม?
Ole VV

1

วิธีเปรียบเทียบวันที่ 2 วัน (util.date หรือ sql.date)

 public static boolean isSameDay(Date a, Date b) {
    Calendar calA = new GregorianCalendar();
    calA.setTime(a);

    Calendar calB = new GregorianCalendar();
    calB.setTime(b);

    final int yearA = calA.get(Calendar.YEAR);
    final int monthA = calA.get(Calendar.MONTH);
    final int dayA = calA.get(Calendar.DAY_OF_YEAR);

    final int yearB = calB.get(Calendar.YEAR);
    final int monthB = calB.get(Calendar.MONTH);
    final int dayB = calB.get(Calendar.DAY_OF_YEAR);

    return yearA == yearB && monthA == monthB && dayA == dayB;
}

0

ลองกับสิ่งนี้

public static String toMysqlDateStr(Date date) {
    String dateForMySql = "";
    if (date == null) {
        dateForMySql = null;
    } else {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateForMySql = sdf.format(date);
    }

    return dateForMySql;
}

-1

ฉันคิดว่าวิธีที่ดีที่สุดในการแปลงคือ:

static java.sql.Timestamp SQLDateTime(Long utilDate) {
    return new java.sql.Timestamp(utilDate);
}

Date date = new Date();
java.sql.Timestamp dt = SQLDateTime(date.getTime());

หากคุณต้องการแทรกdtตัวแปรลงในตาราง SQL คุณสามารถทำได้:

insert into table (expireAt) values ('"+dt+"');

1
สิ่งนี้ดูเหมือนจะเป็นคำตอบเดียวกับที่โพสต์เมื่อปีที่แล้ว
Bernhard Barker

-3

ฉันใช้รหัสต่อไปนี้โปรดลองใช้งาน

DateFormat fm= new SimpleDateFormatter();

ระบุรูปแบบวันที่ที่คุณต้องการสำหรับตัวอย่าง"DD-MM_YYYY"หรือ'YYYY-mm-dd' จากนั้นใช้ประเภทข้อมูล Java เป็นวันที่

fm.format("object of java.util.date");

จากนั้นมันจะแยกวิเคราะห์วันที่ของคุณ


-3

คุณสามารถใช้วิธีนี้ในการแปลงวันที่ใช้เป็นวันที่ sql

DateUtilities.convertUtilDateToSql(java.util.Date)

ไม่มีคลาส DateUtilities ในไลบรารี Java มาตรฐาน (และฉันไม่สามารถหาวิธีนี้ได้จากการค้นหาโดย Google อย่างรวดเร็ว) หากนี่มาจากห้องสมุดเฉพาะคุณอาจต้องการพูดมากและรวมลิงค์ไปยังเอกสาร
Bernhard Barker

-4

ฉันพยายามเข้ารหัสต่อไปนี้ซึ่งใช้งานได้ดี

java.util.Date utilDate = new java.util.Date ();
java.sql.Date sqlDate = ใหม่ java.sql.Date (utilDate);


-8

หากคุณเป็น usgin Mysql คอลัมน์วันที่สามารถส่งผ่านการเป็นตัวแทนสตริงของวันที่นี้

ดังนั้นฉันใช้ DateFormatter Class เพื่อจัดรูปแบบแล้วตั้งเป็น String ในคำสั่ง sql หรือคำสั่งที่เตรียมไว้

นี่คือภาพประกอบรหัส:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

String date = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// จากนั้นส่งผ่านวันที่นี้ในคำสั่ง sql ของคุณ


14
ยินดีต้อนรับสู่ stackoverflow ฉันมีความคิดเห็นเล็กน้อยสำหรับคำตอบของคุณ คำถามคือ "วิธีการแปลง java.util.Date เป็น java.sql.Date" รหัสที่คุณวางรูปแบบเป็น java.util.Date เป็น yyyy-MM-dd นี่คือการใช้งานที่ จำกัด ในบริบทนี้เนื่องจากคุณควรส่ง java.sql.Date โดยตรงไปยังไดรเวอร์ jdbc แทนที่จะใช้เป็นสตริง
jontro
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.