2012-01-18 9 views
8

Tak, kolejne pytanie dotyczące daty w Javie i Javascript.JavaScript Data i java.util.Date argument konstruktora

Strefa czasowa to GMT + 4 (Moskwa) w przeglądarce Java i przeglądarce (Chrome).

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

Daje: Sun Jun 01 1975 00:00:00 GMT + 0400 (Russian Standard Time)

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); 
    } 
} 

Daje: Sob 31 maja 23:00:00 MSK 1975

Jeśli Zmieniam wartość epoki na taką jak 2011-2012 rok (po tym, jak w Rosji zostało anulowane światło dzienne) dane wyjściowe są prawidłowe. Narzędzie do aktualizacji timezone działało OK.

Czy to błąd czy udokumentowana funkcja? Czy jest jakiś sposób, aby poradzić sobie z tym wyjątkiem formatowania i ponownego parsowania jak YYYY-MM-dd HH: mm: SS lub tak?

z javadoc:

Data (długi data)

alokuje obiekt Data i inicjuje to reprezentuje określoną liczbę milisekund od czasu standardowego podstawowej znanej jako „epoki”, a mianowicie od 1 stycznia , 1970, 00:00:00 GMT.

z odniesieniem javascript:

new Date (ms)

milisekund - Wartość całkowita reprezentująca liczbę milisekund od 1 stycznia 1970 r 00:00:00 UTC (Unix Epoch).

+0

Może to ma coś wspólnego ze "zmianami strefy czasowej": http://en.wikipedia.org/wiki/Moscow_Time –

+0

To definitywnie jest. Czy to oznacza, że ​​konstruktora daty nie można już używać w javascript? – ike3

+0

Cóż, jeśli jedno z nich podaje właściwą odpowiedź, ale nie drugą, to powiedziałbym, że druga ma błąd :-) Czy Java jest poprawna czy jest JavaScript? Chciałbym oczekiwać, że wersja Java udzieli właściwej odpowiedzi, ale to tylko podejrzenie. – Pointy

Odpowiedz

1

Jest to błąd lub udokumentowane cecha?

To nie jest błąd w JavaScript. Przynajmniej nie widzę sposobu, żeby to potwierdzić.

Silnik przeglądarki w przeglądarce zwraca czas skonwertowany na "GMT + 4". Najwidoczniej jest to MSK, który różni się od GMT + 4 (jak zaznaczono w twoim komentarzu). JavaScript nie wiedząc o MSK nie liczy się jako błąd, ale brak funkcji. Być może js jest "niewłaściwy", ponieważ nie ma szczegółowej wiedzy o strefach czasowych, ale nie jest to błąd.

Czy istnieje jakiś sposób, aby sobie z tym poradzić oprócz formatowania i ponownego analizowania jak yyyy-MM-DD GG: MM: SS lub tak?

Śledzenie wszystkich arbitralnych szczegółów stref czasowych wymaga dużo pracy. Nie znam takiej bazy kodu, która ma całą tę pracę dostępną dla javascript. Dlatego uważam, że tak, musisz ręcznie zakodować tę konwersję, jeśli chcesz używać prawdziwego MSK.

1

Ciąg znaków reprezentujący czas (jak "Sun Jun 01 1975 00:00:00 GMT+0400") jest używany dla człowieka. Wartość czasu (milisekundy od 1 stycznia, 1970 UTC) są używane do przechowywania i obliczania.

Nie ma tam błędu. W JavaScript, zgodnie ze specyfikacją, contente reprezentacji napisów jest zależne od implementacji.W języku Java, zgodnie z dokumentacją, można odzwierciedlić czas letni może.

Od JavaScript specification:

15.9.5.2 Date.prototype.toString ()

Funkcja ta zwraca wartość ciągu. Treść ciągu znaków zależy od implementacji->, ale ma na celu reprezentację daty w bieżącej strefie czasowej w wygodnej, czytelnej dla człowieka formie.

Od 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

... i ...

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

1975-05-31T23: 00 + 03: 00 [Europa/Moskwa]

Zobacz live code.

Korzystanie java.time

nowoczesne podejście zastosowano klasy java.time w Java 8 i późniejszych.

Używasz kłopotliwych starych klas daty i czasu na Javie, które są już starsze. Wśród wielu problemów na tych klasach była dobrze przemyślana, ale myląca cecha metody Date::toString, która stosowała bieżącą domyślną strefę czasową podczas generowania ciągu znaków. Wewnętrzna wartość jest zawsze zawsze w UTC, ale toString tworzy złudzenie, że Date ma strefę czasową, podczas gdy w rzeczywistości tak się nie dzieje. To wyjaśnia tajemnicę MSK.

[Jeszcze bardziej zagmatwany, w rzeczywistości jest strefa czasowa pochowana głęboko w Date, ale nie ma znaczenia dla tej dyskusji. Te stare klasy są okropnym bałaganem. Na szczęście Java ma teraz najlepszą w swojej klasie strukturę czasu na dowolnej platformie: java.time.]

Najwyraźniej dane wejściowe reprezentują liczbę milisekund od czasów uniksowych 1970-01-01T00: 00: 00Z.

Klasa Instant reprezentuje moment na osi czasu w UTC z rozdzielczością nanoseconds (do dziewięciu (9) cyfr ułamka dziesiętnego). Ta klasa może bezpośrednio analizować twój numer wejściowy.

Instant instant = Instant.ofEpochMilli(170_798_400_000L) ; 

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

Jeśli chcesz zobaczyć tej samej chwili przez pryzmat konkretnego regionu wall-clock time, stosuje się czas strefa.Zastosuj obiekt ZoneId, aby uzyskać obiekt ZonedDateTime.

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

1975-05-31T23: 00 + 03: 00 [Europa/Moskwa]

JavaScript Biblioteka jest niepoprawne

Wyniki rozmowy do JavaScript Biblioteka jest niepoprawny z jego offsetem +04: 00. According to Wikipedia, Moskwa od 1930 do 1981 roku była trzy godziny do przodu, +03: 00. Ramy java.time dają poprawne wyniki +03: 00 przez cały rok 1975. Aby uzyskać więcej informacji, zobacz Time in Russia. Zastrzeżenie: Nie jestem ekspertem w Rosji/Związku Radzieckim.


O java.time

Ramy java.time jest wbudowana w Java 8 i późniejszych. Klasy te zastępują kłopotliwe stare klasy z datami, takie jak java.util.Date, Calendar, & SimpleDateFormat.

Projekt Joda-Time, teraz w maintenance mode, zaleca migrację do klas java.time. Aby uzyskać więcej informacji, zobacz

. I wyszukaj Stack Overflow dla wielu przykładów i objaśnień. Specyfikacja to JSR 310.

Gdzie można uzyskać lekcje java.time?

Projekt ThreeTen-Extra rozciąga java.time z dodatkowych zajęć. Ten projekt jest poligonem wskazującym na możliwe przyszłe dodatki do java.time. Możesz znaleźć tutaj kilka użytecznych klas, takich jak Interval, YearWeek, YearQuarter i more.

Powiązane problemy