Làm cách nào để chuyển đổi java.util.Date thành java.sql.Date?


453

Tôi đang cố gắng sử dụng java.util.Datenhư là một đầu vào và sau đó tạo một truy vấn với nó - vì vậy tôi cần một java.sql.Date.

Tôi đã rất ngạc nhiên khi thấy rằng nó không thể thực hiện chuyển đổi hoàn toàn hoặc rõ ràng - nhưng tôi thậm chí không biết tôi sẽ làm điều này như thế nào, vì API Java vẫn còn khá mới đối với tôi.


Bạn có thể tìm thấy một vấn đề tương tự ở đây stackoverflow.com/questions/12131068/ từ
Lem

Đối với tôi, hóa ra tôi không cần phải chuyển đổi. Có một import java.sql.*mã trong mã của tôi, ghi đè java.util.date và do đó gây ra sự cố khi gán giá trị ngày tốt với giá trị sau nhưng không phải là giá trị đầu tiên. HTH
HumanInDisguise

1
@DavidAckerman Bạn có hiểu rằng java.util.Date là một ngày thời gian, nhưng java.sql.Date chỉ là một ngày mà không có thời gian trong ngày? (Trên thực tế có một thời gian trong ngày nhưng bị bỏ qua, một lỗi xấu của thiết kế lớp) Trong SQL, DATEcó nghĩa là chỉ ngày.
Basil Bourque

2
Tôi thực sự không nhận thức được các sắc thái trong '09, và vì câu hỏi này rất phổ biến, tôi đã thay đổi câu trả lời được chấp nhận thành một câu trả lời hiện đại và hoàn chỉnh hơn. Cảm ơn tất cả mọi người cho đầu vào của bạn!
David Ackerman

Câu trả lời:


89

tl; dr

Làm cách nào để chuyển đổi java.util.Date thành java.sql.Date?

Đừng. Cả hai lớp đều lỗi thời.

  • Sử dụng các lớp java.time thay vì kế thừa java.util.Date& java.sql.Datevới JDBC 4.2 trở lên.
  • Chuyển đổi sang / từ java.time nếu hoạt động liên tục với mã chưa được cập nhật thành java.time.

Ví dụ truy vấn với 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.
)

Thay thế:

  • Instantthay vì java.util.Date
    cả hai đại diện cho một khoảnh khắc trong UTC. nhưng bây giờ với nano giây thay vì mili giây.
  • LocalDatethay vì java.sql.Date
    Cả hai đại diện cho một giá trị chỉ ngày mà không có thời gian trong ngày và không có múi giờ.

Chi tiết

Nếu bạn đang cố gắng làm việc với các giá trị chỉ ngày (không có thời gian trong ngày, không có múi giờ), hãy sử dụng LocalDatelớp thay vì java.util.Date.

Bảng các loại thời gian ngày trong Java (cả di sản và hiện đại) và trong tiêu chuẩn SQL.

java.time

Trong Java 8 trở lên, các lớp thời gian cũ rắc rối được gói cùng với các phiên bản đầu tiên của Java đã được thay thế bởi gói java.time mới . Xem Hướng dẫn của Oracle . Phần lớn chức năng đã được chuyển sang Java 6 & 7 trong ThreeTen-Backport và được điều chỉnh phù hợp hơn với Android trong ThreeTenABP .

Một kiểu dữ liệu SQL DATE có nghĩa là chỉ ngày, không có thời gian trong ngày và không có múi giờ. Java chưa bao giờ có một lớp chính xác như vậy cho đến khi java.time.LocalDateở Java 8. Hãy tạo ra một giá trị như vậy bằng cách lấy ngày hôm nay theo một múi giờ cụ thể (múi giờ rất quan trọng trong việc xác định một ngày là một ngày mới khởi đầu sớm hơn ở Paris so với ở Montréal, thí dụ).

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".

Tại thời điểm này, chúng tôi có thể được thực hiện. Nếu bạn điều khiển JDBC Tuân JDBC 4.2 đặc tả , bạn sẽ có thể vượt qua một LocalDatequa setObjecttrên PreparedStatementđể lưu trữ vào một lĩnh vực SQL DATE.

myPreparedStatement.setObject( 1 , localDate );

Tương tự, sử dụng ResultSet::getObjectđể tìm nạp từ cột DATE SQL đến một LocalDateđối tượng Java . Việc chỉ định lớp trong đối số thứ hai làm cho mã của bạn an toàn .

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

Nói cách khác, toàn bộ Câu hỏi này không liên quan theo JDBC 4.2 trở lên.

Nếu trình điều khiển JDBC của bạn không thực hiện theo cách này, bạn cần quay lại chuyển đổi sang các loại java.sql.

Chuyển đổi sang java.sql.Date

Để chuyển đổi, sử dụng các phương thức mới được thêm vào các lớp thời gian cũ. Chúng ta có thể gọi java.sql.Date.valueOf(…)để chuyển đổi a LocalDate.

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

Và đi theo hướng khác.

LocalDate localDate = sqlDate.toLocalDate();

Chuyển đổi từ java.util.Date

Mặc dù bạn nên tránh sử dụng các lớp thời gian cũ, bạn có thể bị buộc phải làm việc với mã hiện có. Nếu vậy, bạn có thể chuyển đổi sang / từ java.time.

Đi qua Instantlớp, đại diện cho một khoảnh khắc trên dòng thời gian trong UTC. An Instantlà ý tưởng tương tự như a java.util.Date. Nhưng lưu ý rằng Instantcó độ phân giải lên tới nano giây trong khi java.util.Datechỉ có độ phân giải mili giây .

Để chuyển đổi, sử dụng các phương thức mới được thêm vào các lớp cũ. Ví dụ, java.util.Date.from( Instant )java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

Để xác định một ngày, chúng ta cần bối cảnh của múi giờ. Đối với bất kỳ thời điểm nào, ngày thay đổi trên toàn cầu theo múi giờ. Áp dụng a ZoneIdđể có được a ZonedDateTime.

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

† Các java.sql.Date giả vờ lớp là ngày-chỉ mà không có một ngày thời gian-of-nhưng thực sự làm một thời gian trong ngày, điều chỉnh đến một thời gian nửa đêm. Gây nhầm lẫn? Vâng, các lớp thời gian cũ là một mớ hỗn độn.


Giới thiệu về java.time

Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date, Calendar, & SimpleDateFormat.

Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.

Để tìm hiểu thêm, xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của bạn. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*lớp.

Nơi để có được các lớp java.time?

Bảng mà thư viện java.time sẽ sử dụng với phiên bản Java hoặc Android nào

Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là một nền tảng chứng minh cho các bổ sung có thể trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval, YearWeek, YearQuarter, và nhiều hơn nữa .


478

Đừng bận tâm....

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);

  }

}

giải thích nó Liên kết là http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htmlm


34
Đây không phải là một chuyển đổi rõ ràng! Từ Javadoc: "Nếu giá trị mili giây đã cho chứa thông tin thời gian, trình điều khiển sẽ đặt các thành phần thời gian thành thời gian theo múi giờ mặc định (múi giờ của máy ảo Java chạy ứng dụng) tương ứng với 0 GMT." Vì vậy, bất kể thời gian của bạn trên java.util.Date là bao nhiêu, nó sẽ được chèn vào lúc 00:00:00 trong một cột với kiểu dữ liệu được đặt thành DATE.

1
@David Ackerman ..... phương thức này trả về epochsecondstức là mili giây sau 1,JAN,1970. Nhưng điều gì sẽ xảy ra nếu chúng ta muốn lưu trữ ngày của một người trước ngày này .... hoặc đại loại như0000-00-00 as default
Arjun KP

31
Trong trường hợp của tôi, câu trả lời đúng là <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (producDate.getTime ()); </ code>, vì nó bảo toàn các trường thời gian.
Alberto de Paola

2
@ Wired00 Có, các lớp thời gian cũ đi kèm với các phiên bản đầu tiên của Java là một mớ hỗn độn , được thiết kế tồi bao gồm một số hack thô. Bất cứ khi nào có thể, hãy thử sử dụng khung java.time mới trong Java 8 trở lên. Những lớp học mới thay thế cái cũ. Các lớp java.time và các lớp cũ có một số phương thức thuận tiện để chuyển đổi qua lại - hữu ích trong khi chúng tôi chờ trình điều khiển JDBC được cập nhật để sử dụng trực tiếp các loại java.time mới.
Basil Bourque

1
@ Wired00 Xem Câu trả lời mới của tôi về Câu hỏi này để biết cách sử dụng java.time. Cũng tìm kiếm StackOverflow để biết thêm nhiều ví dụ.
Basil Bourque

39

Với câu trả lời khác, bạn có thể gặp rắc rối với thông tin về thời gian (so sánh ngày với kết quả không mong muốn!)

Tôi đề nghị:

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
Nếu anh ta đang sử dụng java.sql.Date cho cột Ngày trong cơ sở dữ liệu, thông tin thời gian đó sẽ bị cắt ngắn. Tôi đã áp đảo giải pháp theo ý kiến ​​của tôi.
darioo

4
Vâng, có lẽ tôi đã làm nó. Đôi khi tôi cần so sánh java.sql.Data với ngày hiện tại và imho đây là cách tốt nhất. Tôi hy vọng nó có thể giúp đỡ.
mauretto

FYI, người già lớp ngày thời gian khủng khiếp phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle .
Basil Bourque

Tất nhiên, chủ đề này là khoảng 10 năm trước, tiền java 8.
mauretto

26

Hàm này sẽ trả về một ngày SQL được chuyển đổi từ đối tượng ngày java.

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

18

Chuyển đổi java.util.Datađể java.sql.Datasẽ mất giờ, phút và giây. Vì vậy, nếu có thể, tôi khuyên bạn nên sử dụng java.sql.Timestampnhư thế này:

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

Để biết thêm thông tin, bạn có thể kiểm tra câu hỏi này .


16

Trong trường hợp tôi chọn ngày từ JXDatePicker (java calender) và nhận nó được lưu trữ trong cơ sở dữ liệu dưới dạng loại Ngày SQL, bên dưới hoạt động tốt ..

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

trong đó PickDate là đối tượng của JXDatePicker


5

Hàm này sẽ trả về một ngày SQL được chuyển đổi từ đối tượng ngày java.

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

Định dạng java.util.Date của bạn đầu tiên. Sau đó sử dụng ngày được định dạng để lấy ngày trong 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

Dưới đây là ví dụ về việc chuyển đổi ngày Util sang ngày Sql và đây là một ví dụ về những gì tôi đang sử dụng trong dự án của mình cũng có thể hữu ích cho bạn.

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

Tôi là một người mới: sau nhiều hoạt động xung quanh này đã làm việc. Suy nghĩ có thể hữu ích

     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, người già lớp ngày thời gian khủng khiếp phiền hà như java.util.Date, java.util.Calendarjava.text.SimpleDateFormatbây giờ là di sản , thay thế bởi sự java.time class built vào Java 8 và sau đó. Xem Hướng dẫn của Oracle .
Basil Bourque

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

Ở đây javaDate là ví dụ của java.util.Date


1
Nó dường như không thực sự thêm bất cứ điều gì mới so với câu trả lời của David Ackerman, chetan và Tanmay kumar Shaw, phải không?
Ole VV

1

Phương pháp để so sánh 2 ngày (produc.date hoặc 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

thử cái này

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

Tôi nghĩ cách tốt nhất để chuyển đổi là:

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

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

Nếu bạn muốn chèn dtbiến vào bảng SQL, bạn có thể thực hiện:

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

1
Điều này dường như về cơ bản giống như câu trả lời này được đăng một năm trước.
Bernhard Barker

-3

tôi đang sử dụng đoạn mã sau đây

DateFormat fm= new SimpleDateFormatter();

xác định định dạng của ngày bạn muốn ví dụ "DD-MM_YYYY"hoặc 'YYYY-mm-dd' sau đó sử dụng kiểu dữ liệu Ngày java như

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

sau đó nó sẽ phân tích ngày của bạn


-3

Bạn có thể sử dụng phương pháp này để chuyển đổi ngày tận dụng thành ngày sql,

DateUtilities.convertUtilDateToSql(java.util.Date)

Không có lớp DateUtilities trong thư viện Java tiêu chuẩn (và tôi thậm chí không thể tìm thấy phương thức này ở bất cứ đâu từ một tìm kiếm nhanh của Google). Nếu đây là từ một thư viện cụ thể, bạn có thể muốn nói nhiều và bao gồm một liên kết đến các tài liệu.
Bernhard Barker

-4

Tôi đã thử mã hóa sau đây hoạt động tốt.

java.util.Date producDate = new java.util.Date ();
java.sql.Date sqlDate = new java.sql.Date (producDate);


-8

Nếu bạn đang sử dụng Mysql, một cột ngày có thể được thông qua biểu diễn Chuỗi của ngày này

Vì vậy, tôi sử dụng Lớp DateFormatter để định dạng nó và sau đó đặt nó làm Chuỗi trong câu lệnh sql hoặc câu lệnh đã chuẩn bị

đây là hình minh họa mã:

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

Chuỗi ngày = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// sau đó vượt qua ngày này trong câu lệnh sql của bạn


14
Chào mừng bạn đến với stackoverflow, tôi có một vài bình luận cho câu trả lời của bạn. Câu hỏi là "làm thế nào để chuyển đổi java.util.Date thành java.sql.Date". Mã bạn đã dán định dạng java.util.Date là yyyy-MM-dd. Điều này thực sự được sử dụng hạn chế trong ngữ cảnh này vì bạn nên truyền trực tiếp java.sql.Date cho trình điều khiển jdbc thay vì thực hiện dưới dạng chuỗi.
jontro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.