tl; dr
OffsetDateTime.now().getOffset()
Nhưng bạn có thể nên sử dụng múi giờ thay vì chỉ chênh lệch từ UTC.
ZoneId.systemDefault()
Chênh lệch so với Múi giờ
Phần bù từ UTC chỉ đơn thuần là một số giờ, phút và giây - không có gì hơn. Ví dụ: -08:00
có nghĩa là chậm hơn UTC tám giờ và +05:45
có nghĩa là trước UTC năm giờ bốn mươi lăm phút .
Một múi giờ là một lịch sử của quá khứ, hiện tại, và những thay đổi trong tương lai để bù đắp được sử dụng bởi những người của một khu vực cụ thể. Các hiện tượng bất thường như Giờ tiết kiệm ánh sáng ban ngày (DST) gây ra sự thay đổi trong khoảng thời gian cụ thể được theo dõi theo thời gian, trong quá khứ khi chúng xảy ra và trong tương lai khi các chính trị gia công bố các thay đổi theo kế hoạch.
Vì vậy, tốt hơn là sử dụng một khu vực khi được biết đến.
Phần bù cho bất kỳ vùng nào cũng thay đổi theo thời gian. Ví dụ: DST ở Hoa Kỳ thay đổi mức bù một giờ trong khoảng nửa năm và sau đó khôi phục giờ đó trở lại mức bù trong nửa năm còn lại. Toàn bộ mục đích của múi giờ là để ghi lại những thay đổi đó theo hướng bù đắp.
Vì vậy, thực sự không có ý nghĩa gì khi yêu cầu bù trừ mà không có ngày-giờ . Trong America/Los_Angeles
, ví dụ như trong một phần của năm nay bù đắp là -08:00
nhưng trong một phần khác của năm đó là -07:00
trong DST.
OffsetDateTime
Vì vậy, hãy xác định một khoảnh khắc như một OffsetDateTime
, và sau đó giải nén ZoneOffset
.
OffsetDateTime odt = OffsetDateTime.now ();
ZoneOffset zoneOffset = odt.getOffset ();
odt.toString (): 2017-01-02T15: 19: 47.162-08: 00
zoneOffset.toString (): -08: 00
now
Phương pháp đó thực sự đang áp dụng ngầm múi giờ mặc định hiện tại của JVM. Tôi khuyên bạn nên luôn làm rõ điều đó bằng cách chỉ định múi giờ mong muốn / dự kiến của bạn. Ngay cả khi bạn muốn vùng mặc định hiện tại, hãy nói rõ ràng như vậy để làm rõ ý định của bạn. Loại bỏ sự mơ hồ về việc bạn dự định mặc định hay không xem xét múi giờ như thường xảy ra với các lập trình viên. Gọi điện thoại ZoneId.systemDefault
.
OffsetDateTime odt = OffsetDateTime.now ( ZoneId.systemDefault () );
ZoneOffset zoneOffset = odt.getOffset ();
ZoneId.systemDefault (). ToString (): America / Los_Angeles
odt: 2017-01-02T15: 19: 47.162-08: 00
zoneOffsetOfOdt: -08: 00
Lưu ý về việc tùy thuộc vào vùng mặc định: Mặc định này có thể được thay đổi bất kỳ lúc nào bằng bất kỳ mã nào trong bất kỳ chuỗi nào trong JVM. Nếu quan trọng, hãy hỏi người dùng về múi giờ dự định của họ.
Bạn có thể yêu cầu phần bù cho lượng thời gian của nó dưới dạng tổng số giây.
int offsetSeconds = zoneOffset.getTotalSeconds ();
offsetSeconds: -28800
ZonedDateTime
Một ví dụ khác: Có lẽ bạn muốn biết mức bù đắp vào Ngày Giáng sinh năm nay ở Québec. Chỉ định múi giờ America/Montreal
, lấy a ZonedDateTime
, yêu cầu độ lệch của nó như một ZoneOffset
đối tượng.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.of( 2017 , 12 , 25 );
ZonedDateTime zdtXmas = ld.atStartOfDay( z );
ZoneOffset zoneOffsetXmas = zdtXmas.getOffset();
zdtXmas.toString (): 2017-12-25T00: 00-05: 00 [Mỹ / Montreal]
zoneOffsetXmas.toString (): -05: 00
zoneOffsetXmas.getTotalSeconds (): -18000
ZoneId
Như được đề xuất trong nhận xét của yanys, bạn có thể thẩm vấn a ZoneId
cho một cụ thể ZoneOffset
bằng cách chuyển một thời điểm dưới dạng 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).
Đây chỉ là một tuyến đường khác đến cùng một điểm đến. Cũng giống như với OffsetDateTime
và ZonedDateTime
thảo luận ở trên, chúng tôi đang chỉ định (a) múi giờ và (b) một thời điểm.
Instant instant = zdtXmas.toInstant();
ZoneOffset zo = z.getRules().getOffset( instant );
Đối với ZoneId: America / Montreal vào thời điểm tức thì: 2017-12-25T05: 00: 00Z ZoneOffset là: -05: 00
Xem tất cả mã của các ví dụ này trực tiếp tại IdeOne.com .
ZoneOffset.systemDefault
- Lỗi hoặc tính năng?
Các ZoneOffset
lớp, một lớp con của ZoneId
, là tài liệu như kế thừa các systemDefault
phương pháp. Tuy nhiên, điều này không thực sự hoạt động.
ZoneOffset zoneOffset = ZoneOffset.systemDefault() ;
lỗi: các loại không tương thích: Không thể chuyển đổi ZoneId thành ZoneOffset
Không chắc liệu lỗi biên dịch này là lỗi hay một tính năng. Như đã thảo luận ở trên, dường như tôi không bao giờ yêu cầu bù đắp mặc định với ngày-giờ, vì vậy có lẽ ZoneOffset.systemDefault
thực tế sẽ không thành công. Nhưng tài liệu sẽ nói như vậy, kèm theo lời giải thích.
Tôi đã cố gắng gửi một lỗi về lỗi tài liệu không giải quyết được vấn đề này, nhưng đã bỏ cuộc, không thể xác định vị trí và cách gửi một báo cáo lỗi như vậy.
Giờ mặt trời so với giờ chính trị
Thông tin thêm về hiệu số và múi giờ…
Thời gian Mặt trời đã được sử dụng từ trước lịch sử, theo dõi mỗi ngày bằng cách ghi lại thời điểm mặt trời ở trên cao. Chọc một cây gậy xuống đất, và quan sát bóng của nó. Khi bóng tối ngắn nhất, khi bóng bắt đầu lớn hơn chứ không phải nhỏ lại, thì bạn biết bây giờ là buổi trưa. Chính thức hóa điều đó bằng đồng hồ mặt trời để theo dõi thời gian trôi qua.
Với thời gian mặt trời, khi bạn đi từ thị trấn này sang thị trấn khác di chuyển về phía tây, buổi trưa sẽ đến muộn hơn một chút. Di chuyển về phía đông, buổi trưa đến sớm hơn một chút. Vì vậy, mỗi thị trấn đều có buổi trưa riêng, chỉ dùng chung với các thị trấn ở phía bắc và nam dọc theo cùng một kinh độ.
Thời gian mặt trời phần lớn đã bị bỏ rơi trong kỷ nguyên hiện đại. Khi xe lửa, điện tín và điện thoại đến, nhu cầu phối hợp tạm thời cũng vậy. Vì vậy, một điểm được chọn cho thời gian mặt trời gần của buổi trưa, và một vùng đất rộng lớn rất nhiều dặm về phía tây và phía đông được công bố cho tất cả các cổ phiếu cùng 12:00 vào đồng hồ, cùng một số giờ bù đắp trước hay đằng sau Greenwich Meridian Thủ dòng . Vì vậy, bắt đầu truyền thống mỗi trạm dừng xe lửa hiển thị nổi bật một chiếc đồng hồ để cho thị trấn biết về thời gian tiêu chuẩn cho khu vực lớn hơn của họ thay vì giờ mặt trời cho thị trấn của họ. Nói chung, các thị trấn ở rìa phía tây của khu vực múi giờ đó sẽ thấy đồng hồ ga tàu của họ chỉ trước 12:00 một chútmặt trời ở trên cao. Đồng hồ ở các thị trấn ở rìa phía đông của khu vực chỉ điểm 12 giờ trưa sau khi mặt trời ló dạng.
Các chính trị gia trên khắp thế giới cho thấy xu hướng thay đổi (các) phần bù của quyền tài phán của họ. Các lý do khác nhau, chẳng hạn như ngoại giao, chiến tranh và chiếm đóng, và sự im lặng của Giờ tiết kiệm ánh sáng ban ngày (DST) . Các lý do khác nhau, nhưng những thay đổi của chúng đi kèm với tần suất đáng ngạc nhiên. Múi giờ là tên được đặt cho một khu vực để theo dõi lịch sử của những thay đổi đó. Vì vậy, một offset-from-UTC chỉ đơn thuần là một số giờ-phút-giây trước hoặc sau kinh tuyến gốc. Một múi giờ là nhiều hơn nữa: một lịch sử của quá khứ, hiện tại, và những thay đổi trong tương lai để offsets của một khu vực cụ thể. Mặc dù hai khu vực lân cận ngày nay có thể chia sẻ cùng một khoảng chênh lệch so với UTC, trong quá khứ hoặc tương lai chúng có thể khác nhau tùy thuộc vào ý tưởng bất chợt hoặc logic khác nhau của các chính trị gia của họ.
Điều này có nghĩa là việc theo dõi thời gian hiện đại do các chính trị gia xác định hầu như không liên quan đến địa lý. Ví dụ: đất nước Ấn Độ khổng lồ ngày nay có một múi giờ duy nhất (offset-from-UTC là +05: 30). Vì vậy, buổi trưa mặt trời (mặt trời chiếu thẳng qua đầu bạn) cách nhau hàng giờ ở nhiều nơi khác nhau trên khắp tiểu lục địa rộng lớn. Các chính trị gia của Ấn Độ quyết định điều này để giúp thống nhất nền dân chủ đa dạng của họ. Trong các ví dụ khác trên thế giới, chúng ta thấy các khu vực sử dụng múi giờ của họ làm biểu tượng cho quan hệ quốc tế, chẳng hạn như khác với quốc gia láng giềng đang xúc phạm hoặc chọn cùng múi giờ với nước láng giềng khi quan hệ tan băng như đã thấy gần đây ở Triều Tiên thay đổi để phù hợp Nam Triều Tiên. Vì vậy, ngày nay, thời gian mặt trời chỉ là một trong số những điều cần cân nhắc trong việc theo dõi thời gian.
Giới thiệu về java.time
Các java.time khung được xây dựng vào Java 8 và sau đó. Các lớp này thay thế các lớp ngày-giờ kế thừa cũ rắc rối 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 để có 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 dây, không cầnjava.sql.*
lớp. Hibernate 5 & JPA 2.2 hỗ trợ java.time .
Lấy các lớp java.time ở đâu?
ZoneOffset.systemDefault()