2012-01-18 29 views
8

Có, một câu hỏi khác về Ngày tháng trong Java và Javascript.Ngày Javascript và đối số hàm tạo java.util.Date

Múi giờ GMT + 4 (Moscow) cả trong Java và Trình duyệt (Chrome).

<script language="javascript"> 
    var d = new Date(170798400000); 
    document.write(d); 
</script> 

Cung cấp: Sun 01 tháng sáu 1975 00:00:00 GMT + 0400 (Nga Giờ chuẩn)

public class Test { 
    public static void main(String[] args) { 
     java.util.Date d = new java.util.Date(170798400000L); // the same epoch value! 
     System.out.println(d); 
    } 
} 

Cung cấp: Sat 31 tháng 5 23:00:00 MSK 1975

Nếu Tôi thay đổi giá trị kỷ nguyên thành một cái gì đó giống như năm 2011-2012 (sau khi tiết kiệm ánh sáng ban ngày đã bị hủy bỏ ở Nga) đầu ra là OK. Công cụ cập nhật múi giờ đã chạy OK.

Đây có phải là lỗi hoặc tính năng được ghi chép không? Có cách nào để xử lý điều này ngoại trừ định dạng và phân tích cú pháp lại như YYYY-MM-dd HH: mm: SS hay không?

từ javadoc:

ngày (ngày dài)

Phân bổ một đối tượng Date và khởi tạo nó để đại diện cho số quy định của mili giây kể từ thời điểm cơ sở tiêu chuẩn gọi là "kỷ nguyên", cụ thể là 01 tháng 1 , 1970, 00:00:00 GMT.

từ tài liệu tham khảo javascript:

new Date (mili giây)

mili giây - Integer giá trị thể hiện số mili giây kể từ ngày 01 tháng một năm 1970 00:00:00 UTC (Unix Epoch).

+0

Có thể điều này liên quan đến "Thay đổi múi giờ": http://en.wikipedia.org/wiki/Moscow_Time –

+0

Chắc chắn là như vậy. Điều đó có nghĩa là Date constructor không thể được sử dụng trong javascript nữa? – ike3

+0

Vâng, nếu một trong số họ đưa ra câu trả lời đúng, nhưng không phải là câu trả lời đúng, thì tôi muốn nói câu trả lời khác có lỗi :-) Java có đúng hay là JavaScript? Tôi sắp xếp kỳ vọng phiên bản Java để đưa ra câu trả lời đúng, nhưng đó chỉ là một sự nghi ngờ. – Pointy

Trả lời

1

Đây có phải là lỗi hoặc tính năng được ghi chép không?

Đây không phải là lỗi với Javascript. Ít nhất, tôi thấy không có cách nào tôi có thể tuyên bố điều đó.

Công cụ Javascript của trình duyệt đang trả về thời gian được chuyển thành "GMT + 4". Những gì bạn đang muốn, rõ ràng, là MSK mà là khác nhau từ GMT + 4 (như đã nêu trong bình luận của bạn). Javascript không biết về MSK không được tính là lỗi, nhưng thiếu tính năng. Có lẽ js là "sai" vì không có kiến ​​thức chi tiết về múi giờ, nhưng nó không phải là lỗi.

Có cách nào để xử lý việc này ngoại trừ định dạng và phân tích cú pháp lại như YYYY-MM-dd HH: mm: SS hay không?

Việc theo dõi tất cả các chi tiết tùy ý của múi giờ đòi hỏi nhiều công việc. Tôi biết không có codebase như vậy mà có tất cả những gì làm việc có sẵn cho javascript. Do đó, tôi tin rằng, có, bạn sẽ phải tự mã hóa chuyển đổi đó nếu bạn muốn sử dụng MSK thực sự.

1

Biểu thị chuỗi thời gian (như "Sun Jun 01 1975 00:00:00 GMT+0400") được sử dụng cho con người. Giá trị thời gian (mili giây kể từ ngày 1 tháng 1 năm 1970) được sử dụng để lưu trữ và tính toán.

Không có lỗi ở đó. Trong JavaScript, theo đặc điểm kỹ thuật, contente của biểu diễn chuỗi phụ thuộc vào việc triển khai thực hiện.Trong Java, theo tài liệu, thời gian tiết kiệm ánh sáng ban ngày có thể được phản ánh.

Từ JavaScript specification:

15.9.5.2 Date.prototype.toString ()

Hàm này trả về một giá trị String. Nội dung của chuỗi được thực hiện-> phụ thuộc, nhưng được dự định để đại diện cho ngày trong múi giờ hiện tại ở dạng thuận tiện, có thể đọc được.

Từ Java documentation:

java.util.Date, public String toString() 

Converts this Date object to a String of the form: dow mon dd hh:mm:ss zzz yyyy 

where: 
... 
zzz is the time zone (and may reflect daylight saving time).` 
0

tl; dr

Instant.ofEpochMilli(170_798_400_000L) 

1975-05-31T20: 00: 00Z

... và ...

Instant.ofEpochMilli(170_798_400_000L) 
     .atZone(ZoneId.of("Europe/Moscow")) 

1975-05-31T23: 00 + 03: 00 [Châu Âu/Moscow]

Xem live code.

Sử dụng java.time

Cách tiếp cận hiện đại sử dụng các lớp java.time trong Java 8 trở lên.

Bạn đang sử dụng các lớp ngày giờ khó xử cũ trong Java hiện là cũ. Trong số nhiều vấn đề trên các lớp đó là tính năng có chủ ý nhưng khó hiểu của phương pháp Date::toString áp dụng múi giờ mặc định hiện tại trong khi tạo chuỗi. Giá trị bên trong thực sự luôn ở dạng UTC, nhưng toString tạo ra ảo giác rằng Date có múi giờ khi thực tế nó không có. Điều đó giải thích bí ẩn của bạn MSK.

[Thậm chí còn khó hiểu hơn, thực tế là múi giờ được chôn sâu trong Date nhưng không liên quan đến cuộc thảo luận này. Những lớp học cũ Date/Calendar là một mớ hỗn độn khủng khiếp. May mắn là Java hiện có khung thời gian tốt nhất trong mọi nền tảng: java.time.]

Rõ ràng đầu vào của bạn biểu thị số mili giây từ kỷ nguyên Unix 1970-01-01T00: 00: 00Z.

Lớp Instant đại diện cho một thời điểm trên dòng thời gian ở UTC với độ phân giải nanoseconds (tối đa chín (9) chữ số thập phân). Lớp này có thể phân tích trực tiếp số đầu vào của bạn.

Instant instant = Instant.ofEpochMilli(170_798_400_000L) ; 

instant.toString(): 1975-05-31T20: 00: 00Z

Nếu bạn muốn để thấy rằng cùng một thời điểm thông qua ống kính của một khu vực cụ thể của wall-clock time, áp dụng một thời gian vùng.Áp dụng một số ZoneId để nhận đối tượng ZonedDateTime.

ZoneId z = ZoneId.of("Europe/Moscow") ; 
ZonedDateTime zdt = instant.atZone(z) ; 

1975-05-31T23: 00 + 03: 00 [Châu Âu/Moscow]

thư viện JavaScript là không chính xác

Kết quả của cuộc gọi của bạn đến thư viện JavaScript là không chính xác với độ lệch của nó là +04: 00. According to Wikipedia, thời gian Moscow từ 1930 đến 1981 là ba giờ trước, +03: 00. Khung công tác java.time mang lại kết quả chính xác của +03: 00 trong suốt năm 1975. Xem Time in Russia để biết thêm thông tin. Caveat: Tôi không phải là chuyên gia thời Nga/Liên Xô.


Về java.time

Khung java.time được xây dựng vào Java 8 và sau đó. Các lớp này thay thế các lớp học ngày giờ legacy phiền hà cũ như java.util.Date, Calendar, & SimpleDateFormat.

Dự án Joda-Time, hiện đang ở maintenance mode, khuyên di chuyển đến các lớp java.time.

Để tìm hiểu thêm, hãy xem Oracle Tutorial. 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.

Nơi lấy các lớp java.time?

Dự án mở rộng ThreeTen-Extra 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 những bổ sung có thể có trong tương lai vào java.time. Bạn có thể tìm thấy một số lớp học hữu ích tại đây như Interval, YearWeek, YearQuartermore.

Các vấn đề liên quan