tl; dr
myUtilDate.toInstant() // Convert `java.util.Date` to `Instant`.
.atOffset( ZoneOffset.UTC ) // Transform `Instant` to `OffsetDateTime`.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // Generate a String.
.replace( "T" , " " ) // Put a SPACE in the middle.
2014/11/14 14:05:09
java.time
Cách hiện đại là với các lớp java.time mà bây giờ thay thế các lớp thời gian cũ kế thừa rắc rối.
Đầu tiên chuyển đổi của bạn java.util.Date
để một Instant
. Các Instant
lớp đại diện cho một thời điểm trên Timeline trong UTC với độ phân giải nano giây (lên đến chín (9) chữ số của một phân số thập phân).
Chuyển đổi đến / từ java.time được thực hiện bằng các phương thức mới được thêm vào các lớp cũ.
Instant instant = myUtilDate.toInstant();
Cả bạn java.util.Date
và java.time.Instant
đang ở UTC . Nếu bạn muốn xem ngày và giờ là UTC, thì hãy là nó. Gọi toString
để tạo Chuỗi theo định dạng ISO 8601 tiêu chuẩn .
String output = instant.toString();
2014-11-14T14: 05: 09Z
Đối với các định dạng khác, bạn cần chuyển đổi Instant
thành linh hoạt hơn OffsetDateTime
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
odt.toString (): 2020-05-01T21: 25: 35.957Z
Xem mã đó chạy trực tiếp tại IdeOne.com .
Để có được một Chuỗi ở định dạng mong muốn của bạn, chỉ định a DateTimeFormatter
. Bạn có thể chỉ định một định dạng tùy chỉnh. Nhưng tôi sẽ sử dụng một trong các trình định dạng được xác định trước ( ISO_LOCAL_DATE_TIME
) và thay thế T
đầu ra của nó bằng SPACE.
String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " );
2014/11/14 14:05:09
Bằng cách này, tôi không đề xuất loại định dạng này khi bạn cố tình làm mất thông tin bù từ UTC hoặc múi giờ. Tạo sự mơ hồ về ý nghĩa của giá trị thời gian ngày của chuỗi đó.
Ngoài ra, hãy cẩn thận với việc mất dữ liệu, vì bất kỳ giây phân đoạn nào đang bị bỏ qua (bị cắt ngắn một cách hiệu quả) trong biểu diễn chuỗi giá trị ngày của bạn.
Để xem cùng thời điểm đó qua ống kính của thời gian đồng hồ treo tường của một số khu vực cụ thể , hãy áp dụng a ZoneId
để có được a ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
zdt.toString (): 2014-11-14T14: 05: 09-05: 00 [Mỹ / Montreal]
Để tạo một chuỗi được định dạng, làm tương tự như trên nhưng thay thế odt
bằng zdt
.
String output = zdt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " );
2014/11/14 14:05:09
Nếu thực thi mã này một số lần rất lớn, bạn có thể muốn hiệu quả hơn một chút và tránh cuộc gọi đến String::replace
. Bỏ cuộc gọi đó cũng làm cho mã của bạn ngắn hơn. Nếu muốn, chỉ định mẫu định dạng của riêng bạn trong DateTimeFormatter
đối tượng của riêng bạn . Cache trường hợp này là một hằng số hoặc thành viên để sử dụng lại.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ); // Data-loss: Dropping any fractional second.
Áp dụng định dạng đó bằng cách chuyển thể hiện.
String output = zdt.format( f );
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ác lớp học ngày thời gian cũ phiền hà như java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
.
Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang java.time.
Để 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.
Phần lớn chức năng java.time được chuyển ngược lại sang Java 6 & 7 trong ThreeTen-Backport và được điều chỉnh thêm cho Android trong ThreeTenABP (xem Cách sử dụng Thẻ ).
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.