timezone java Warum ergibt das Abziehen dieser beiden Male (1927) ein seltsames Ergebnis?




4 Answers

Sie haben eine Ortszeitunterbrechung festgestellt :

Als die lokale Normalzeit kurz vor dem Sonntag, 1. Januar 1928, 00:00:00 Uhr war, wurde die Uhrzeit um 0:05:52 Uhr auf Samstag, 31. Dezember 1927, 23:54:08 Uhr zurückgestellt

Das ist nicht sonderbar seltsam und hat sich zu einem oder anderen Zeitpunkt fast überall ereignet, da die Zeitzonen aufgrund von politischen oder administrativen Maßnahmen geändert oder geändert wurden.

java date convert timezone

Wenn ich das folgende Programm ausführen, werden zwei Datumsfolgen im Abstand von 1 Sekunde analysiert und miteinander verglichen:

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

Die Ausgabe ist:

353

Warum ist ld4-ld3 nicht 1 (wie ich es von dem Zeitunterschied von einer Sekunde erwarten würde), sondern 353 ?

Wenn ich die Datumsangaben in Sekunden später umstelle:

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

Dann wird ld4-ld3 1 .

Java-Version:

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



Wenn Sie die Zeit inkrementieren, sollten Sie wieder in UTC konvertieren und dann addieren oder subtrahieren. Verwenden Sie nur die Ortszeit für die Anzeige.

Auf diese Weise können Sie alle Zeiträume durchlaufen, in denen Stunden oder Minuten zweimal vorkommen.

Wenn Sie in UTC konvertiert haben, fügen Sie jede Sekunde hinzu und konvertieren Sie sie in lokale Zeit für die Anzeige. Sie würden durch 11:54:08 Uhr LMT - 23:59:59 Uhr LMT und dann um 11:54:08 Uhr CST - 23:59:59 Uhr CST gehen.




Es tut mir leid, das sagen zu müssen, aber die Diskontinuität hat sich etwas verschoben

JDK 6 vor zwei Jahren und in JDK 7 vor kurzem in Update 25 .

Lektion zu lernen: Vermeiden Sie unter allen Umständen Nicht-UTC-Zeiten, mit Ausnahme der Anzeige.




IMHO die durchdringende, implizite Lokalisierung in Java ist der größte Konstruktionsfehler. Es ist zwar für Benutzeroberflächen gedacht, aber ehrlich gesagt, wer Java heute wirklich für Benutzeroberflächen verwendet, mit Ausnahme einiger IDEs, bei denen Sie die Lokalisierung grundsätzlich ignorieren können, weil Programmierer nicht genau die Zielgruppe dafür sind. Sie können das Problem (insbesondere auf Linux-Servern) beheben, indem Sie

  • export LC_ALL = C TZ = UTC
  • Stellen Sie Ihre Systemuhr auf UTC
  • Verwenden Sie niemals lokalisierte Implementierungen, es sei denn, dies ist unbedingt erforderlich (dh nur zur Anzeige).

Den Mitgliedern des Java Community Process empfehle ich:

  • machen lokalisierte Methoden nicht zum Standard, sondern verlangen, dass der Benutzer die Lokalisierung explizit anfordert.
  • Verwenden Sie stattdessen UTF-8 / UTC als FIXED- Standard, da dies heute einfach der Standard ist. Es gibt keinen Grund, etwas anderes zu tun, es sei denn, Sie möchten solche Threads erstellen.

Ich meine, komm schon, sind globale statische Variablen kein Anti-OO-Muster? Nichts anderes sind diese durchdringenden Standardeinstellungen, die durch einige rudimentäre Umgebungsvariablen vorgegeben werden.




Related