2012-01-18 14 views
8

Sì, un'altra domanda su Date in Java e Javascript.Data Javascript e argomento costruttore java.util.Date

Il fuso orario è GMT + 4 (Mosca) sia in Java che in Browser (Chrome).

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

Dà: Sun 1 Giugno 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); 
    } 
} 

Dà: Sab 31 Mag 23:00:00 MSK 1975

Se Io cambio il valore dell'epoca in qualcosa come l'anno 2011-2012 (dopo che l'ora legale è stata cancellata in Russia) l'output è OK. Lo strumento di aggiornamento di Timezone ha funzionato correttamente.

Si tratta di un bug o di una funzionalità documentata? C'è un modo per gestirlo tranne la formattazione e la ri-analisi come YYYY-MM-dd HH: mm: SS o giù di lì?

da javadoc:

Data (lunga data)

alloca un oggetto Date e inizializza per rappresentare il numero specificato di millisecondi dal tempo base tipo noto come "epoca", cioè January 1 , 1970, 00:00:00 GMT.

da riferimento javascript:

new Date (millisecondi)

millisecondi - valore intero che rappresenta il numero di millisecondi dal 1 Gen 1970 00:00:00 GMT (Unix Epoch).

+0

Forse questo ha qualcosa a che fare con "Fusi orari cambia": http://en.wikipedia.org/wiki/Moscow_Time –

+0

Lo è sicuramente. Ciò significa che il costruttore Date non può più essere utilizzato in javascript? – ike3

+0

Beh, se uno di questi sta dando la risposta giusta, ma non l'altro, allora direi che l'altro ha un bug :-) Java è corretto o è JavaScript? Mi aspetterei che la versione Java dia la risposta giusta, ma questo è solo un sospetto. – Pointy

risposta

1

Si tratta di un bug o di una funzionalità documentata?

Questo non è un bug con Javascript. Almeno, non vedo come potrei affermarlo.

Il motore Javascript del browser sta restituendo l'ora convertita in "GMT + 4". Apparentemente, quello che stai cercando è MSK, che è diverso da GMT + 4 (come notato nel tuo commento). Javascript non sapendo di MSK non conta come un bug, ma una mancanza di una funzionalità. Forse js è "sbagliato" per non avere quella conoscenza dettagliata dei fusi orari, ma non è un bug.

C'è un modo per gestirlo tranne la formattazione e la ri-analisi come YYYY-MM-dd HH: mm: SS o così?

Tenere traccia di tutti i dettagli arbitrari dei fusi orari richiede molto lavoro. Non conosco tale base di codice che ha tutto quel lavoro disponibile per javascript. Pertanto, credo che, sì, dovresti codificare manualmente la conversione da te se vuoi utilizzare vero MSK.

1

Le stringhe di tempo (come "Sun Jun 01 1975 00:00:00 GMT+0400") vengono utilizzate per l'uomo. Il valore temporale (millisecondi dal 1 gennaio 1970 UTC) viene utilizzato per la memorizzazione e il calcolo.

Non c'è nessun bug lì. In JavaScript, in base alle specifiche, il contente della rappresentazione stringa è dipendente dall'implementazione.In Java, secondo la documentazione, l'ora legale può essere riflessa.

Da JavaScript specification:

15.9.5.2 Date.prototype.toString ()

questa funzione restituisce un valore Stringa. I contenuti della stringa sono implementazione-> dipendenti, ma sono intesi per rappresentare la data nel fuso orario corrente in un formato conveniente, leggibile dall'uomo.

Da 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

... e ...

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

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

Vedi live code.

Utilizzando java.time

L'approccio moderno utilizza le classi java.time in Java 8 e versioni successive.

Si stanno utilizzando classi fastidiose di data e ora in Java che ora sono legacy. Tra i molti problemi su quelle classi c'era la ben intenzionata, ma confusa, caratteristica del metodo Date::toString che applicava il fuso orario predefinito corrente durante la generazione della stringa. Il valore interno è in realtà sempre in UTC, ma l'toString crea l'illusione che lo Date abbia un fuso orario quando in realtà non lo è. Questo spiega il tuo mistero MSK.

[Ancora più confuso, in realtà è un fuso orario sepolto in profondità Date ma è irrilevante a questa discussione. Quelle vecchie classi Date/Calendar sono un pasticcio terribile. Fortunatamente Java ora dispone della migliore struttura data-ora su qualsiasi piattaforma: java.time.]

Apparentemente l'input rappresenta il numero di millisecondi dall'epoca Unix di 1970-01-01T00: 00: 00Z.

La classe Instant rappresenta un momento sulla timeline in UTC con una risoluzione di nanoseconds (fino a nove (9) cifre di una frazione decimale). Questa classe può analizzare direttamente il tuo numero di input.

Instant instant = Instant.ofEpochMilli(170_798_400_000L) ; 

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

Se volete vedere quello stesso momento attraverso la lente di una particolare regione del wall-clock time, applicare un tempo zona.Applicare uno ZoneId per ottenere un oggetto ZonedDateTime.

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

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

libreria JavaScript è corretto

I risultati della chiamata al libreria JavaScript è errato con il suo offset di +04: 00. According to Wikipedia, l'ora di Mosca dal 1930 al 1981 era tre ore avanti, +03: 00. Il framework java.time restituisce risultati corretti di +03: 00 per tutto l'anno del 1975. Vedi Time in Russia per maggiori informazioni. Avvertenza: non sono esperto in Russia/tempo sovietico.


Chi java.time

Il quadro java.time è costruito in Java 8 e versioni successive. Queste classi soppiantano le fastidiose classi data legacy come java.util.Date, Calendar, & SimpleDateFormat.

Il progetto Joda-Time, ora in maintenance mode, consiglia la migrazione alle classi java.time.

Per ulteriori informazioni, vedere Oracle Tutorial. E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310.

Dove ottenere le classi java.time?

Il progetto ThreeTen-Extra java.time prolunga con classi aggiuntive. Questo progetto è un terreno di prova per possibili aggiunte future a java.time. È possibile trovare alcune classi utili come Interval, YearWeek, YearQuarter e more.