tl; dr
Instant.now() // Capture the current moment in UTC.
Tạo một chuỗi để biểu thị giá trị đó:
Instant.now().toString()
2016-09-13T23: 30: 52.123Z
Chi tiết
Như câu trả lời đúng bởi Jon Skeet nói, một đối tượng java.util.Date có không múi giờ † . Nhưng việc toString
triển khai nó áp dụng múi giờ mặc định của JVM khi tạo biểu diễn Chuỗi của giá trị thời gian ngày đó. Khó hiểu với lập trình viên ngây thơ, một Ngày dường như có múi giờ nhưng không.
Các java.util.Date
, j.u.Calendar
và java.text.SimpleDateFormat
các lớp học kèm với Java nổi tiếng là phiền hà. Tránh chúng. Thay vào đó, hãy sử dụng một trong những thư viện thời gian có thẩm quyền này:
java.time (Java 8)
Java 8 mang đến một gói java.time. * Mới tuyệt vời để thay thế các lớp java.util.Date/CalWiki cũ.
Có được thời gian hiện tại trong UTC / GMT là một trò chơi đơn giản
Instant instant = Instant.now();
Instant
Lớp đó là khối xây dựng cơ bản trong java.time, đại diện cho một khoảnh khắc trên dòng thời gian trong UTC với độ phân giải nano giây .
Trong Java 8, khoảnh khắc hiện tại được ghi lại chỉ với độ phân giải lên đến mili giây. Java 9 mang đến một triển khai mới để Clock
ghi lại khoảnh khắc hiện tại với khả năng đầy đủ nano giây của lớp này, tùy thuộc vào khả năng của phần cứng đồng hồ của máy chủ của bạn.
Đó là toString
phương pháp tạo ra một chuỗi đại diện giá trị của nó sử dụng một định dạng cụ thể theo tiêu chuẩn ISO 8601 . Định dạng đó tạo ra các chữ số 0, ba, sáu hoặc chín chữ số ( mili giây , micro giây hoặc nano giây ) khi cần để biểu thị phân số của giây.
Nếu bạn muốn định dạng linh hoạt hơn hoặc các tính năng bổ sung khác, thì hãy áp dụng offset từ UTC bằng 0, cho chính UTC ( ZoneOffset.UTC
không đổi ) để có được a OffsetDateTime
.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
Kết xuất giao diện điều khiển
System.out.println( "now.toString(): " + now );
Khi chạy đào
now.toString(): 2014-01-21T23:42:03.522Z
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, 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 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?
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 .
Joda-Thời gian
CẬP NHẬT: Dự án Joda-Time , hiện ở chế độ bảo trì , khuyên chuyển sang các lớp java.time .
Sử dụng thư viện miễn phí mã nguồn mở của bên thứ ba Joda , bạn có thể có được thời gian ngày hiện tại chỉ trong một dòng mã.
Joda-Time đã truyền cảm hứng cho các lớp java.time. * Mới trong Java 8, nhưng có kiến trúc khác. Bạn có thể sử dụng Joda-Time trong các phiên bản Java cũ hơn. Joda-Time tiếp tục hoạt động trong Java 8 và tiếp tục được duy trì tích cực (kể từ năm 2014). Tuy nhiên, nhóm Joda-Time không khuyên di chuyển sang java.time.
System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
Mã ví dụ chi tiết hơn (Joda-Time 2.3)
org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
Kết xuất giao diện điều khiển
System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );
Khi chạy đào
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
Để biết thêm ví dụ mã thực hiện công việc múi giờ, hãy xem câu trả lời của tôi cho một câu hỏi tương tự.
Múi giờ
Tôi khuyên bạn luôn luôn chỉ định múi giờ thay vì dựa hoàn toàn vào múi giờ mặc định hiện tại của JVM (có thể thay đổi bất cứ lúc nào!). Sự phụ thuộc như vậy dường như là một nguyên nhân phổ biến của sự nhầm lẫn và lỗi trong công việc thời gian.
Khi gọi now()
vượt qua múi giờ mong muốn / dự kiến sẽ được chỉ định. Sử dụng DateTimeZone
lớp học.
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );
Lớp đó giữ một hằng số cho múi giờ UTC .
DateTime now = DateTime.now( DateTimeZone.UTC );
Nếu bạn thực sự muốn sử dụng múi giờ mặc định hiện tại của JVM, hãy thực hiện một cuộc gọi rõ ràng để mã của bạn tự ghi lại.
DateTimeZone zoneDefault = DateTimeZone.getDefault();
ISO 8601
Đọc về các định dạng ISO 8601 . Cả java.time và Joda-Time đều sử dụng các định dạng hợp lý của tiêu chuẩn đó làm mặc định cho cả phân tích cú pháp và tạo chuỗi.
† Trên thực tế, java.util.Date không có một múi giờ, chôn sâu dưới lớp mã nguồn. Đối với hầu hết các mục đích thực tế, múi giờ đó bị bỏ qua. Vì vậy, như tốc ký, chúng tôi nói java.util.Date không có múi giờ. Hơn nữa, múi giờ bị chôn vùi đó không phải là múi giờ được sử dụng bởi toString
phương pháp của Date ; phương thức đó sử dụng múi giờ mặc định hiện tại của JVM. Tất cả lý do nhiều hơn để tránh lớp khó hiểu này và gắn bó với Joda-Time và java.time.