[Java] Warum werden diese beiden Zeiten (1927) subtrahiert, was zu einem seltsamen Ergebnis führt?



Answers

Sie haben eine lokale Zeitunterbrechung festgestellt :

Als die lokale Standardzeit am Sonntag, dem 1. Januar 1928, zu erreichen war, wurden 00:00:00 Uhren 0:05:52 Stunden bis Samstag, 31. Dezember 1927, 23:54:08 Uhr Ortszeit rückwärts gedreht

Dies ist nicht besonders merkwürdig und ist zu jeder Zeit überall passiert, da Zeitzonen aufgrund von politischen oder administrativen Maßnahmen gewechselt oder geändert wurden.

Question

Wenn ich das folgende Programm ausführe, das zwei Datumszeichenfolgen referenziert, die 1 Sekunde auseinander verweisen, und vergleicht sie:

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 von dem Unterschied von einer Sekunde in der Zeit erwarten würde), sondern 353 ?

Wenn ich die Daten um 1 Sekunde später ändere:

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 erhöhen, sollten Sie zurück in UTC konvertieren und dann addieren oder subtrahieren. Verwenden Sie die lokale Zeit nur 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 die lokale Zeit für die Anzeige. Du würdest 23:54:08 Uhr LMT - 23:59:59 Uhr LMT und dann 11:54:08 Uhr CST - 23:59:59 Uhr CST durchgehen.




IMHO ist die durchdringende, implizite Lokalisierung in Java der größte Konstruktionsfehler. Es kann für Benutzerschnittstellen gedacht sein, aber ehrlich gesagt, wer Java wirklich für Benutzeroberflächen heute benutzt, außer für einige IDEs, wo Sie Lokalisierung grundsätzlich ignorieren können, weil Programmierer nicht genau die Zielgruppe dafür sind. Sie können es (vor allem auf Linux-Servern) folgendermaßen beheben:

  • export LC_ALL = C TZ = UTC
  • Stellen Sie Ihre Systemuhr auf UTC ein
  • Verwenden Sie niemals lokalisierte Implementierungen, es sei denn, dies ist absolut notwendig (dh nur für die Anzeige)

Den Mitgliedern des Java Community Process empfehle ich:

  • lokalisierte Methoden nicht als Standard festlegen, sondern vom Benutzer explizit eine Lokalisierung anfordern.
  • Benutze stattdessen UTF-8 / UTC als FIXED- Standard, da dies einfach der Standard ist. Es gibt keinen Grund, etwas anderes zu tun, außer wenn Sie solche Threads erzeugen möchten.

Ich meine, komm schon, sind keine globalen statischen Variablen ein Anti-OO-Muster? Nichts anderes sind diese allgegenwärtigen Defaults, die von einigen rudimentären Umgebungsvariablen gegeben werden .......




Tut mir leid, das zu sagen, aber die Zeitverschiebung hat sich ein wenig verschoben

JDK 6 vor zwei Jahren und in JDK 7 erst kürzlich in Update 25 .

Lektion zu lernen: vermeiden Sie nicht-UTC Zeiten um jeden Preis, außer vielleicht für die Anzeige.




Links