[JAVA] Sommerproblem auch in Japan

Apropos Sommerzeit, es war die Rede davon, die Sommerzeit als Maßnahme gegen die Hitze der Olympischen Spiele einzuführen. Es war unmöglich und diese Geschichte floss so wie sie war. Solange ich in Japan war, dachte ich, dass die Sommerzeit nichts damit zu tun hat, aber in Japan bin ich auf einen Fehler gestoßen, der durch die Sommerzeit verursacht wurde. Dieser Artikel ist das Ende davon.

Aus irgendeinem Grund einen Tag weniger

Ich habe eine Schleife wie diese ausgeführt, um Daten zu Datumsangaben zu erstellen:

Calendar cal = new GregorianCalendar(1900,  1 - 1,  1, 0, 0, 0);
Calendar end = new GregorianCalendar(2020, 12 - 1, 31, 0, 0, 0);
long endTime = end.getTimeInMillis();

while (cal.getTimeInMills() <= endtime) {
     // (Datumsdatenerstellung)
     cal.add(Calendar.DATE, 1);
}

Ich versuche Daten von 1900/01/01 bis 2020/12/31 zu erstellen. Die erstellten Datumsdaten sind jedoch einen Tag kürzer. Daten sollten bis 2020/12/31 erstellt werden, jedoch nur bis 2020/12/30. Wenn ich mir also den Inhalt des Datums ansehe,

1900/01/01 00:00:00.000
1900/01/02 00:00:00.000
1900/01/03 00:00:00.000

(Unterlassung)

2020/12/28 01:00:00.000
2020/12/29 01:00:00.000
2020/12/30 01:00:00.000

Irgendwo um eine Stunde entfernt. endtime zeigte auf 2020/12/31 00: 00: 00.000, daher scheint das Ergebnis einen Tag weniger zu sein.

Tritt bei älteren JDKs nicht auf

Dies geschah auf jdk-8u191, aber nicht auf älteren JDKs.

1900/01/01 00:00:00.000
1900/01/02 00:00:00.000
1900/01/03 00:00:00.000

(Unterlassung)

2020/12/28 00:00:00.000
2020/12/29 00:00:00.000
2020/12/30 00:00:00.000
2020/12/31 00:00:00.000

Und es funktioniert wie erwartet. Wenn Sie genauer hinschauen,

Ich fand heraus. Wurde während dieser Zeit Entfettungsmittel im JDK gemischt? Ich habe verschiedene Dinge durchgearbeitet, aber ich konnte eine solche Seite nicht finden. Wenn ich dann versuche herauszufinden, wo es ist,

1948/04/29 00:00:00.000
1948/04/30 00:00:00.000
1948/05/01 00:00:00.000
1948/05/02 01:00:00.000
1948/05/03 01:00:00.000
1948/05/04 01:00:00.000

Es ist am 1948/05/02 aus. Dachte ich und als ich in Japans Sommerzeit herumging

IANA Data 2018c JDK 8u171 contains IANA time zone data version 2018c. For more information, refer to Timezone Data Versions in the JRE Software.

Es fällt mit dem ersten Tag der Sommerzeit in Japan am 2. Mai 1948 zusammen. Ist dies passiert, weil die japanische Sommerzeit in jdk-8u171 implementiert wurde? ?? ?? Wenn ich mir das JDK-Changelog jdk-8u171 Changelog ansehe, kann ich keine Erwähnung der Sommerzeit in Japan finden. In Bezug auf Zeitzonendatenversionen in der JRE-Software gab es um 2014 Änderungen in Bezug auf Japan. Kann gelesen werden, aber so etwas gibt es in jdk-8u171 nicht. Wenn Sie sich das Änderungsprotokoll von jdk-8u171 oben genauer ansehen, finden Sie die folgende Beschreibung. Zeitzonendaten wurden aktualisiert. Also werde ich versuchen, dies zu treffen.

Sommerzeitdaten (Zeitzonendaten)

https://www.iana.org/time-zones

Scheint die Quelle für Zeitzonendaten zu sein. Betrachtet man den Unterschied zwischen "tzdb-2018c" und dem vorherigen "tzdb-2018b",

tzdb-2018b 2018-01-18 08:50 asia:

# Rule	NAME	FROM	TO	TYPE	IN	ON		AT	    SAVE	LETTER/S
Rule	Japan	1948	only	-	May	Sun>=1	2:00	1:00	D
Rule	Japan	1948	1951	-	Sep	Sat>=8	2:00	0		S
Rule	Japan	1949	only	-	Apr	Sun>=1	2:00	1:00	D
Rule	Japan	1950	1951	-	May	Sun>=1	2:00	1:00	D

tzdb-2018c 2018-01-23 10:30 asia:

# Rule	NAME	FROM	TO	TYPE	IN	ON		AT		SAVE	LETTER/S
Rule	Japan	1948	only	-	May	Sat>=1	24:00	1:00	D
Rule	Japan	1948	1951	-	Sep	Sat>=8	25:00	0		S
Rule	Japan	1949	only	-	Apr	Sat>=1	24:00	1:00	D
Rule	Japan	1950	1951	-	May	Sat>=1	24:00	1:00	D

Und sicherlich gibt es Änderungen. Wie man das liest

# Rule	NAME	FROM	TO	TYPE	IN	ON		AT	    SAVE	LETTER/S
Rule	Japan	1948	only	-	May	Sun>=1	2:00	1:00	D
(Erster Samstag im Mai 1948(Erster Samstag nach dem 1 ..)von 2:1 Stunde auf 00 vorrücken)

Es scheint, dass. Der neue ist

# Rule	NAME	FROM	TO	TYPE	IN	ON		AT	    SAVE	LETTER/S
Rule	Japan	1948	only	-	May	Sun>=1	24:00	1:00	D
(Erster Samstag im Mai 1948(Erster Samstag nach dem 1 ..)24:1 Stunde auf 00 vorrücken)

Und die Startzeit der Sommerzeit wurde geändert. Mit anderen Worten, wenn Sie 0 Uhr auf 1 Uhr ändern. Ah!

Was ist passiert

jdk-8u171 hat ein Update in Japans Sommerzeit. Dies ändert die Startzeit der Sommerzeit von 2 Uhr auf 0 Uhr. Da das ursprüngliche Programm um 00: 00: 00 lief

War um eine Stunde weg. Bis dahin war die Startzeit also 2:00 Uhr morgens

Dadurch konnte ich das Datum berechnen, ohne es zu verlieren.

Gegenmaßnahmen

Da die Ursache geklärt wurde, handelt es sich um eine Gegenmaßnahme. Wie man dieses Problem überwindet.

Stellen Sie die Endzeit auf +1 Tag-1 Millisekunde ein

Da die Endzeit 2018/12/31 00:00:00 war, war es ein Tag weniger. Gibt es kein Problem, wenn dies auf 2018/12/31 23:59:59 eingestellt ist?

Calendar end = new GregorianCalendar(2020, 12 - 1, 31, 0, 0, 0);
end.add(Calendar.DATE, 1)
end.add(Calendar.MILLISECOND, -1)
long endTime = end.getTimeInMillis(); // 2018/12/31 23:59:59.999

Sicherlich hat dieses Update wie beabsichtigt funktioniert. Es ist jedoch sehr unangenehm, dass das Datum auf dem Weg auf 01:00:00 zeigt. Auch wenn es hier funktioniert, kann es anderswo Probleme verursachen.

+24 Stunden

Da es cal.add (Calender.DATE, 1) ist, wird es verschoben, und wenn es cal.add (Calender.HOUR, 24) ist, wird es nicht verschoben. Sicher, das Programm hat immer noch wie beabsichtigt funktioniert. Wenn Sie jedoch auf die Zeit schauen

1948/04/29 00:00:00.000
1948/04/30 00:00:00.000
1948/05/01 00:00:00.000
1948/05/02 01:00:00.000
1948/05/03 01:00:00.000
1948/05/04 01:00:00.000
...
1948/09/09 01:00:00.000
1948/09/10 01:00:00.000
1948/09/11 01:00:00.000
1948/09/12 00:00:00.000
1948/09/13 00:00:00.000
1948/09/14 00:00:00.000

Immerhin ist es unterwegs los. Das gleiche Problem tritt also auf, wenn das Enddatum der 09.09.1948 ist. In der Praxis ist dies unwahrscheinlich, aber es ist ein potenzieller Fehler, und ich möchte ihn nach Möglichkeit vermeiden.

+1 Tag .set (00:00:00)

Wie wäre es, wenn Sie die Zeit nach +1 Tag immer auf 00: 00: 00.000 einstellen?

cal.add(Calendar.DATE, 1);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

Dann

1948/04/29 00:00:00.000
1948/04/30 00:00:00.000
1948/05/01 00:00:00.000
1948/05/02 01:00:00.000 //Hier kann nicht geholfen werden
1948/05/03 00:00:00.000
1948/05/04 00:00:00.000
...
1948/09/09 00:00:00.000
1948/09/10 00:00:00.000
1948/09/11 00:00:00.000
1948/09/12 00:00:00.000
1948/09/13 00:00:00.000
1948/09/14 00:00:00.000

Es ist die beabsichtigte Operation. Es fühlt sich jedoch überflüssig an, jedes Mal 00: 00: 00.00 einzustellen. Ich arbeite selten mit Daten von 1948, daher möchte ich nicht jedes Mal die Zeit löschen können.

Verwenden Sie LocalDate

Dann kam ich zu LocalDate. Dies ist eine der Datums- und Uhrzeit-API, die von Java8 eingeführt wurde. LocalDate ist eine Nur-Datum-Klasse ohne Zeitinformationen, daher wird sie nicht von der Sommerzeit beeinflusst. Der vorherige Code ist

LocalDate cal = LocalDate.of(1900,  1,  1);
LocalDate end = LocalDate.of(2018, 12, 31);
long endDay = end.toEpochDay();
			
while (cal.toEpochDay() <= endDay) {
     // (Datumsdatenerstellung)
    cal = cal.plusDays(1); //LocalDate ist unveränderlich
}

Sie können es einfach so in den Code einfügen, wie es ist, ohne eine Problemumgehung vorzunehmen.

Was war das Problem?

Es scheint, dass das Problem darin besteht, dass der gesunde Menschenverstand nicht wie folgt gilt, wenn es Sommerzeit gibt.

Ich dachte, es sei gesunder Menschenverstand. Bis Sie auf diesen Fehler treten. .. ..

Schließlich

Ich hoffe, dass die Sommerzeit in Japan in Zukunft nicht mehr eingeführt wird.

Recommended Posts

Sommerproblem auch in Japan
Über die echte Sommerzeit
So stellen Sie die Anzeigezeit in Rails auf japanische Zeit ein
Verschiedene Renten in Japan