[Java] Perché sottrarre queste due volte (nel 1927) dando uno strano risultato?


Answers

Hai riscontrato una discontinuità nell'ora locale :

Quando l'ora standard locale stava per raggiungere domenica, 1. Gennaio 1928, 00:00:00 gli orologi sono stati girati indietro 0:05:52 ore a sabato 31 dicembre 1927, 23:54:08 ora standard locale

Questo non è particolarmente strano ed è successo praticamente dappertutto in un momento o in un altro quando i fusi orari sono stati cambiati o modificati a causa di azioni politiche o amministrative.

Question

Se eseguo il seguente programma, che analizza due stringhe di data che fanno riferimento a tempi di 1 secondo e li confronta:

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    String str3 = "1927-12-31 23:54:07";  
    String str4 = "1927-12-31 23:54:08";  
    Date sDt3 = sf.parse(str3);  
    Date sDt4 = sf.parse(str4);  
    long ld3 = sDt3.getTime() /1000;  
    long ld4 = sDt4.getTime() /1000;
    System.out.println(ld4-ld3);
}

L'output è:

353

Perché ld4-ld3 non è 1 (come mi aspetterei dalla differenza di un secondo nei tempi), ma 353 ?

Se cambio le date a volte 1 secondo dopo:

String str3 = "1927-12-31 23:54:08";  
String str4 = "1927-12-31 23:54:09";  

Quindi ld4-ld3 sarà 1 .

Versione Java:

java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)

Timezone(`TimeZone.getDefault()`):

sun.util.calendar.ZoneInfo[id="Asia/Shanghai",
offset=28800000,dstSavings=0,
useDaylight=false,
transitions=19,
lastRule=null]

Locale(Locale.getDefault()): zh_CN



IMHO la pervasiva, implicita localizzazione in Java è il suo difetto di progettazione più grande. Può essere inteso per le interfacce utente, ma francamente, chi usa realmente Java per le interfacce utente oggi eccetto per alcuni IDE in cui si può sostanzialmente ignorare la localizzazione perché i programmatori non sono esattamente il pubblico di destinazione per questo. Puoi sistemarlo (specialmente sui server linux) da:

  • esporta LC_ALL = C TZ = UTC
  • imposta il tuo orologio di sistema su UTC
  • non utilizzare mai implementazioni localizzate se non assolutamente necessario (ad es. solo per la visualizzazione)

Ai membri del processo della comunità Java consiglio:

  • rendere i metodi localizzati non predefiniti, ma richiedere all'utente di richiedere esplicitamente la localizzazione.
  • utilizzare UTF-8 / UTC come predefinito FIXED, perché è semplicemente l'impostazione predefinita oggi. Non c'è motivo di fare qualcos'altro, tranne se vuoi produrre discussioni come questa.

Voglio dire, dai, non sono variabili statiche globali un modello anti-OO? Nient'altro sono quelle impostazioni predefinite pervasive date da alcune variabili di ambiente rudimentali .......




Quando si incrementa il tempo, è necessario riconvertire in UTC e quindi aggiungere o sottrarre. Utilizza l'ora locale solo per la visualizzazione.

In questo modo sarai in grado di attraversare tutti i periodi in cui le ore o i minuti si verificano due volte.

Se hai convertito in UTC, aggiungi ogni secondo e converti in ora locale per la visualizzazione. Dovresti passare alle 11:54:08 pm LMT - 11:59:59 pm LMT e poi 11:54:08 CST - 11:59:59 pm CST.




Mi dispiace dirlo, ma la discontinuità nel tempo si è spostata un po '

JDK 6 due anni fa, e in JDK 7 solo recentemente nell'aggiornamento 25 .

Lezione per imparare: evita i tempi non UTC a tutti i costi, tranne, forse, per la visualizzazione.




Links