"date -d" und "tomorrow" am Tag der Sommerzeit-Umstellung

Warum Debian und/oder eine seiner Spielarten? Was muss ich vorher wissen? Wo geht es nach der Installation weiter?
Antworten
cpw83
Beiträge: 3
Registriert: 27.03.2016 17:38:49

"date -d" und "tomorrow" am Tag der Sommerzeit-Umstellung

Beitrag von cpw83 » 27.03.2016 18:05:07

Hallo zusammen,

ich habe heute (27.03.2016, d.h. heute Nacht wurde auf Sommerzeit umgestellt) ein seltsames Verhalten von date auf meinen Jessie-Servern festststellen müssen:

Code: Alles auswählen

date -d 'today 1:59' +%s
1459040340

date -d 'today 2:00' +%s
date: ungültiges Datum „today 2:00“

date -d 'today 3:00' +%s
1459040400
Das ist soweit nachvollziehbar, da diese Uhrzeit heute nicht existierte - die Zeit sprang ja heute Nacht/Morgen direkt von 1:59 auf 3:00 Uhr. 3:00 Uhr war es entsprechend 60 Sekunden nach 1:59 Uhr.

Womit ich allerdings nicht gerechnet habe:

Code: Alles auswählen

date -d 'tomorrow 1:59' +%s
1459123140

date -d 'tomorrow 2:00' +%s
date: ungültiges Datum „tomorrow 2:00“

date -d 'tomorrow 2:59' +%s
date: ungültiges Datum „tomorrow 2:59“

date -d 'tomorrow 3:00' +%s
1459126800
Ich vermute mal, dass der dahinterliegende Algorithmus für "tomorrow" sich zunächst mal "today" anschaut und dann n Sekunden draufschlägt und in diesem Fall bei der entsprechenden heutigen Uhrzeit beginnt, die nicht existiert.

Äußerst unschön - morgen gibt es ja wieder ganz regulär Uhrzeiten zwischen 2:00 und 3:00 Uhr. Ist das ein Bug oder ist dieses Verhalten so bekannt und aus irgendeinem Grund vielleicht sogar erwünscht?

uname
Beiträge: 12474
Registriert: 03.06.2008 09:33:02

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von uname » 27.03.2016 19:59:26

Sieht doch alles gut aus:

Bitte nur heute am Tag der Zeitumstellung probieren, da es an anderen Tagen 3661 ist bzw. bei der Zeitrückstellung im Herbst eine Stunde mehr enthält.

Tag der Zeitumstellung (heute):

Code: Alles auswählen

for ((i=$(date -d 'today 1:59' +%s); i <= $(date -d 'today 3:00' +%s); i++));do echo $i ";" $(date -d @$i);done
Auszug aller 61 Einträge:

Code: Alles auswählen

1459040340 ; So 27. Mär 01:59:00 CET 2016
...
1459040399 ; So 27. Mär 01:59:59 CET 2016
1459040400 ; So 27. Mär 03:00:00 CEST 2016
Ein normaler Tag (morgen):

Code: Alles auswählen

for ((i=$(date -d 'tomorrow 1:59' +%s); i <= $(date -d 'tomorrow 3:00' +%s); i++));do echo $i ";" $(date -d @$i);done
Auszug aller 3661 Einträge:

Code: Alles auswählen

1459123140 ; Mo 28. Mär 01:59:00 CEST 2016
...
1459126800 ; Mo 28. Mär 03:00:00 CEST 2016
Zusammengefasst ist nur wichtig, dass sich die Sekunden nie ändern. Es ändert sich nur der Zusatz CET vs. CEST. Die Basis für die UNIX/Linux-Zeit sind die Sekunden beginnend mit Sekunde 0 am 01.01.1970 um 00:00:00 UTC / 00:00:00 GMT / 01:00:00 CET

Code: Alles auswählen

date -d @0
Do 1. Jan 01:00:00 CET 1970
Für deinen PC ist rein gar nichts passiert. Es ist eigentlich nur die Darstellung geändert worden.

Nachtrag:
Jetzt habe ich dein Problem verstanden. Es schein wirklich ein echtes Problem zu sein. In meiner Routine habe ich die Umrechnung aufgrund existierender Zeiten 01:59 und 03:00 als Intervallgrenzen genommen. Damit hat es funktioniert, da natürlich alle Sekunden fehlerlos existieren.
Aber das scheint umgekehrt wirklich ein Bug zu sein. Bin echt schockiert.

Weiterer Nachtrag:
Ich habe die Zeitumstellungstermine gefunden falls es irgendjemanden interessiert.

Code: Alles auswählen

zdump -c 2018 -v CET 
...
CET  Sun Oct 25 01:00:00 2015 UT = Sun Oct 25 02:00:00 2015 CET isdst=0 gmtoff=3600
CET  Sun Mar 27 00:59:59 2016 UT = Sun Mar 27 01:59:59 2016 CET isdst=0 gmtoff=3600
CET  Sun Mar 27 01:00:00 2016 UT = Sun Mar 27 03:00:00 2016 CEST isdst=1 gmtoff=7200
CET  Sun Oct 30 00:59:59 2016 UT = Sun Oct 30 02:59:59 2016 CEST isdst=1 gmtoff=7200
CET  Sun Oct 30 01:00:00 2016 UT = Sun Oct 30 02:00:00 2016 CET isdst=0 gmtoff=3600
CET  Sun Mar 26 00:59:59 2017 UT = Sun Mar 26 01:59:59 2017 CET isdst=0 gmtoff=3600
...

cpw83
Beiträge: 3
Registriert: 27.03.2016 17:38:49

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von cpw83 » 27.03.2016 20:46:39

uname hat geschrieben:In meiner Routine habe ich die Umrechnung aufgrund existierender Zeiten 01:59 und 03:00 als Intervallgrenzen genommen. Damit hat es funktioniert, da natürlich alle Sekunden fehlerlos existieren.
Aber das scheint umgekehrt wirklich ein Bug zu sein. Bin echt schockiert.
Ich auch, ich möchte nur sicherstellen, dass ich nicht irgendwas übersehe bevor ich einen Bug melde - aber offenbar tue ich das ja tatsächlich nicht.

Code: Alles auswählen

date
So 27. Mär 20:32:26 CEST 2016

date -d 'tomorrow 2:00' +%s
date: ungültiges Datum „tomorrow 2:00“

date -d '2016-03-28 2:00' +%s
1459123200
Also hier offenbar ein reines "tomorrow"-Problem, mit expliziter Datumsangabe ist alles OK.

Wobei mir gerade noch was ein-/auffällt:

Code: Alles auswählen

date -d '2016-03-27 2:00' +%s
date: ungültiges Datum „2016-03-27 2:00“
Das hatte ich jetzt erstmal einfach so hingenommen, aber sollte das nicht eigentlich 1459040400 ausspucken, also entsprechend

Code: Alles auswählen

date -d '2016-03-27 3:00' +%s
, so dass die Unix-Timestamps zwischen 2:00 und 3:00 Uhr lokaler Zeit identisch mit denen zwischen 3:00 und 4:00 Uhr sind?

Ich wills nicht beschwören, meine allerdings mich erinnern zu können, genau das vor einigen Monaten explizit getestet zu haben und nicht auf dieses Problem gestoßen zu sein. Oder hatte ich da evtl. irgendeinen Parameter gesetzt, um immer in UTC zu arbeiten? Hat sich da vielleicht irgendwann innerhalb des letzten Jahres syntaktisch etwas verändert?

dufty2
Beiträge: 1714
Registriert: 22.12.2013 16:41:16

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von dufty2 » 27.03.2016 21:04:36

Code: Alles auswählen

$ date -u -d 'tomorrow 0:00' +%s
1459123200
Witzig, wat? ;)

uname
Beiträge: 12474
Registriert: 03.06.2008 09:33:02

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von uname » 27.03.2016 21:13:48

Ich denke ich habe das Problem gefunden. Das Addieren und Subtrahieren von Tagen bezieht sich eigentlich immer auf die aktuelle Uhrzeit:

Code: Alles auswählen

date -d "tomorrow" +%s
1459192079
Um andere Uhrzeiten statt die aktuelle Uhrzeit nutzen zu können, kann man sie angeben. Hierbei wird die angegebene Uhrzeit umgerechnet und da z.B. ein Tag draufaddiert:

Code: Alles auswählen

date -d "2016-03-27 01:00:00 tomorrow" +%s
1459119600
date -d "2016-03-27 02:00:00 tomorrow" +%s
date: ungültiges Datum „2016-03-27 02:00:00 tomorrow“
date -d "2016-03-27 02:00:00 tomorrow" +%s
date: ungültiges Datum „2016-03-27 02:00:00 tomorrow“
Somit bezieht sich das ungültige Datum nicht auf das Zieldatum, sondern darauf, dass das Startdatum erst gar nicht errechnet werden kann.

Gleiches gilt auch für mehrere Tage:

Code: Alles auswählen

date -d @$(date -d "2016-03-27 03:00:00 10 days" +%s)
date -d @$(date -d "2016-03-27 03:00:00 -10 days" +%s)
26.03.2016 02:30:00 CET + 1 Tag wird wie folgt umgewandelt

Code: Alles auswählen

date -d @$(date -d "2016-03-26 02:30:00 1 days" +%s)
So 27. Mär 03:30:00 CEST 2016
An anderen Stellen ist das Programm wohl nicht ganz konsequent bzw. rechnet mit negativen Sekunden einfach weiter ...

Code: Alles auswählen

date -d @$(date -d "1969-12-31 23:59:00 1 days" +%s)
Do 1. Jan 23:59:00 CET 1970
date -d "1969-12-31 23:59:00" +%s
-3660

dufty2
Beiträge: 1714
Registriert: 22.12.2013 16:41:16

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von dufty2 » 28.03.2016 11:43:06

uname hat geschrieben: An anderen Stellen ist das Programm wohl nicht ganz konsequent bzw. rechnet mit negativen Sekunden einfach weiter ...

Code: Alles auswählen

date -d @$(date -d "1969-12-31 23:59:00 1 days" +%s)
Do 1. Jan 23:59:00 CET 1970
date -d "1969-12-31 23:59:00" +%s
-3660
Mmh, passt doch, ich kann jetzt Dein Problem nicht erkennen.

cpw83
Beiträge: 3
Registriert: 27.03.2016 17:38:49

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von cpw83 » 29.03.2016 14:33:48

uname hat geschrieben: Somit bezieht sich das ungültige Datum nicht auf das Zieldatum, sondern darauf, dass das Startdatum erst gar nicht errechnet werden kann.
Genau das dachte ich mir. Die Frage ist jetzt: Ist das wohl einen Bugreport wert oder ist davon auszugehen, dass das nunmal so funktioniert und nicht änderbar ist? Also handelt es sich hierbei um einen echten Fehler bzw. etwas vermeidbares?
dufty2 hat geschrieben:
uname hat geschrieben: An anderen Stellen ist das Programm wohl nicht ganz konsequent bzw. rechnet mit negativen Sekunden einfach weiter ...

Code: Alles auswählen

date -d @$(date -d "1969-12-31 23:59:00 1 days" +%s)
Do 1. Jan 23:59:00 CET 1970
date -d "1969-12-31 23:59:00" +%s
-3660
Mmh, passt doch, ich kann jetzt Dein Problem nicht erkennen.
Ja, das passt - am 31.12.1969, 23:59:00 Uhr (in unserer GMT/UTC+1-Zeitzone zur Winterzeit!) war es UTC 22:59:00 Uhr, entsprechend 61 Minuten = 3.660 Sekunden vor Unix 0.

uname
Beiträge: 12474
Registriert: 03.06.2008 09:33:02

Re: "date -d" und "tomorrow" am Tag der Sommerzeit-Umstellun

Beitrag von uname » 29.03.2016 14:49:45

Zu meiner Anmerkung. Ich wusste zuvor nur nicht, dass es auch negative Sekunden geben kann.
Wobei eigentlich klar, dass das Überlaufproblem nur bei einer vorzeichenbehafteten 32-Bit-Ganzzahl im Jahr 2038 und nicht erst 68 Jahre später auftritt ;-)

https://de.wikipedia.org/wiki/Jahr-2038-Problem

Bugreport:
Ich würde im übrigen keinen Bugreport schreiben. Ich verstehe mittlerweile "02:00 tomorrow" nicht als morgen 02:00 Uhr, sondern als heute 02:00 Uhr in einem Tag, was nicht immer identisch ist. Am Tag der Umstellung von Winter- auf Sommerzeit existiert heute 02:00 Uhr nicht. Somit ist es korrekt, dass die Berechnung fehlschlägt. Egal was man draufaddiert oder abzieht.

Antworten