tl; dr
LocalDate.of( 2014 , 2 , 11 )
Nếu bạn khăng khăng sử dụng java.util.Date
lớp cũ khủng khiếp , hãy chuyển đổi từ các lớp java.time hiện đại .
java.util.Date
.from(
LocalDate
.of( 2014 , 2 , 11 )
.atStartOfDay(
ZoneId.of( "Africa/Tunis" )
)
.toInstant()
)
Chi tiết
Nếu bạn muốn "dễ dàng", bạn nên sử dụng gói java.time mới trong Java 8 thay vì các lớp java.util.Date & .Calendar nổi tiếng rắc rối đi kèm với Java.
java.time
Các java.time khuôn khổ xây dựng vào Java 8 và sau đó đã thế chỗ các lớp java.util.Date/.Calendar cũ phiền hà.
Chỉ ngày
Một LocalDate
lớp được cung cấp bởi java.time để đại diện cho một giá trị chỉ ngày mà không có bất kỳ thời gian trong ngày hoặc múi giờ nào. Bạn cần một múi giờ để xác định một ngày, ví dụ như một ngày mới ở Paris sớm hơn ở Montréal. Các ZoneId
lớp học là dành cho các múi giờ.
ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
LocalDate today = LocalDate.now( zoneId );
Đổ vào bảng điều khiển:
System.out.println ( "today: " + today + " in zone: " + zoneId );
hôm nay: 2015-11-26 trong khu vực: Châu Á / Singapore
Hoặc sử dụng phương pháp nhà máy để xác định năm, tháng, ngày.
LocalDate localDate = LocalDate.of( 2014 , Month.FEBRUARY , 11 );
localDate: 2014-02-11
Hoặc chuyển một tháng số 1-12 thay vì một DayOfWeek
đối tượng enum.
LocalDate localDate = LocalDate.of( 2014 , 2 , 11 );
Múi giờ
A LocalDate
không có ý nghĩa thực sự cho đến khi bạn điều chỉnh nó thành một múi giờ. Trong java.time, chúng tôi áp dụng múi giờ để tạo một ZonedDateTime
đối tượng. Điều đó cũng có nghĩa là thời gian trong ngày, nhưng thời gian nào? Thường có ý nghĩa khi đi với khoảnh khắc đầu tiên trong ngày. Bạn có thể nghĩ rằng điều đó có nghĩa là thời gian 00:00:00.000
, nhưng không phải lúc nào cũng đúng vì Giờ tiết kiệm ánh sáng ban ngày (DST) và có lẽ là những dị thường khác. Thay vì giả định thời gian đó, chúng tôi yêu cầu java.time xác định thời điểm đầu tiên trong ngày bằng cách gọi atStartOfDay
.
Chỉ định một tên múi giờ thích hợp trong các định dạng của continent/region
, chẳng hạn như America/Montreal
, Africa/Casablanca
hoặc Pacific/Auckland
. Không bao giờ sử dụng từ viết tắt 3-4 chữ cái, chẳng hạn như EST
hoặc IST
vì chúng không phải là múi giờ thực, không được tiêu chuẩn hóa và thậm chí không phải là duy nhất (!).
ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
ZonedDateTime zdt = localDate.atStartOfDay( zoneId );
zdt: 2014-02-11T00: 00 + 08: 00 [Châu Á / Singapore]
UTC
Đối với công việc back-end (logic nghiệp vụ, cơ sở dữ liệu, lưu trữ và trao đổi dữ liệu), chúng tôi thường sử dụng múi giờ UTC . Trong java.time, Instant
lớp biểu thị một thời điểm trên dòng thời gian ở UTC. Một đối tượng Instant có thể được trích xuất từ ZonedDateTime bằng cách gọi toInstant
.
Instant instant = zdt.toInstant();
tức thì: 2014-02-10T16: 00: 00Z
Đổi
Bạn nên tránh sử dụng java.util.Date
hoàn toàn lớp học. Nhưng nếu bạn phải tương tác với mã cũ chưa được cập nhật cho java.time , bạn có thể chuyển đổi qua lại. Tìm kiếm các phương thức chuyển đổi mới được thêm vào các lớp cũ.
java.util.Date d = java.util.from( instant ) ;
… Và…
Instant instant = d.toInstant() ;
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
.
Để tìm hiểu thêm, hãy 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 .
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.
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 mình. 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. Hibernate 5 & JPA 2.2 hỗ trợ java.time .
Lấy các lớp java.time ở đâu?
CẬP NHẬT: Thư viện Joda-Time hiện đang ở chế độ bảo trì và khuyên bạn nên di chuyển sang các lớp java.time . Tôi để lại phần này cho lịch sử.
Joda-Time
Có điều, Joda-Time sử dụng cách đánh số hợp lý nên tháng 2 thì 2
không 1
. Một điều khác, Joda-Time DateTime thực sự biết múi giờ được chỉ định của nó không giống như java.util.Date dường như có múi giờ nhưng không.
Và đừng quên múi giờ. Nếu không, bạn sẽ nhận được mặc định của JVM.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Singapore" );
DateTime dateTimeSingapore = new DateTime( 2014, 2, 11, 0, 0, timeZone );
DateTime dateTimeUtc = dateTimeSingapore.withZone( DateTimeZone.UTC );
java.util.Locale locale = new java.util.Locale( "ms", "SG" );
String output = DateTimeFormat.forStyle( "FF" ).withLocale( locale ).print( dateTimeSingapore );
Đổ vào bảng điều khiển…
System.out.println( "dateTimeSingapore: " + dateTimeSingapore );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "output: " + output );
Khi chạy…
dateTimeSingapore: 2014-02-11T00:00:00.000+08:00
dateTimeUtc: 2014-02-10T16:00:00.000Z
output: Selasa, 2014 Februari 11 00:00:00 SGT
Chuyển đổi
Nếu bạn cần chuyển đổi sang java.util.Date để sử dụng với các lớp khác…
java.util.Date date = dateTimeSingapore.toDate();