Is dround bugged or just confusing? (now with specific timezone)
Git-Boy-Slim opened this issue · 3 comments
Hello,
I wanted to use the special now
of dateutils.dround
with a specific time zone (-z Europe/Berlin
), but after testing it a little bit and comparing the results with date +'%FT%T'
as the timestamp (which should be the same as timezoned now
according to my understanding) I either discovered a bug or confused the hell out of me and didn't understand how dround
is working in the first place.
Could you please explain to me why the results are different, even though the timestamps are initially the same?
This is what I've done:
$ dround -z Europe/Berlin now
=> 2024-04-11T01:24:33
$ dround "$(date +'%FT%T')"
=> 2024-04-11T01:24:33
The "rounded" times without any RNDSPEC
(so the actual current time)
RNDSPEC=1s
$ dround -z Europe/Berlin now 1s -n
=> 2024-04-11T01:25:01
$ dround "$(date +'%FT%T')" 1s -n
=> 2024-04-11T01:25:01
now
and date
print the (imho) correct next occuring time with 01
in the seconds field.
RNDSPEC=1m
$ dround -z Europe/Berlin now 1m -n
=> 2024-04-11T02:01:33
$ dround "$(date +'%FT%T')" 1m -n
=> 2024-04-11T02:01:33
now
and date
both print the (imho) correct next occuring time with 01
in the minute field.
RNDSPEC=1h
$ dround -z Europe/Berlin now 1h -n
=> 2024-04-11T03:24:33
$ dround "$(date +'%FT%T')" 1h -n
=> 2024-04-12T01:24:33
now
prints a time with 03
in the hour field even though 1h
was specified. It also didn't change the day even though the current time is T01:24:33
and therefore next T01:**:**
can only occur the next day.
The output of date
on the other hand is what I expected from this RNDSPEC
.
RNDSPEC=1d
$ dround -z Europe/Berlin now 1d -n
=> 2024-05-02T01:24:33
$ dround "$(date +'%FT%T')" 1d -n
=> 2024-05-01T01:24:33
now
prints a time with 02
in the day field even though 1d
was specified.
The output of date
on the other hand is what I expected from this RNDSPEC
.
RNDSPEC=1mo
$ dround -z Europe/Berlin now 1mo -n
=> 2025-01-11T00:24:33
$ dround "$(date +'%FT%T')" 1mo -n
=> 2025-01-11T01:24:33
now
prints a (imho) correct next occuring date with 01
in the month field. But it shifts the time back one hour even though only 1d
was specified.
The output of date
on the other hand is what I expected from this RNDSPEC
.
I think the confusion is that you expect this to happen:
$ dconv now -z Europe/Berlin | dround <YOUR-RNDSPEC> -n
when in fact this happens:
$ dround now <YOUR-RNDSPEC> -n | dconv -z Europe/Berlin
IOW, the rounding happens first (in UTC time), then is converted to Berlin time.
However, in the last example with your timestamp I get:
$ dround -z Europe/Berlin 2024-04-11T01:24:33 1mo -n
2025-01-11T02:24:33
That is 02:24:33 instead of 00:24:33, or in clocks: an hour ahead instead of behind.
Thank you very much for this fast response.
Now everything does make a lot more sense! And with your explanation I can suddenly see this detail in the man page entry of --zone
too. :)
And you are also right regarding my last example. I just added it later for some kind of completion and may have made a mistake while recording. But this isn't that important for my actual use case.
Actually I want to determine the next occurrence of a specific time (hours:minutes) on a specific day of the month from the present point in time.
And because I live in Berlin time I would like to calculate/round only in that time zone.
Is there a recommended way to accomplish such a task with dateutils
?
Specifically, I want to determine the next possible 15th with a timestamp of 00:42:00
.
$ dround "$(date +'%FT%T')" 00s42m00h15d
=> 2024-04-15T00:42:00
This looked okay to me in the first place, but after your explanation I'm not sure if this is the right way to do it.
You mentioned that the rounding is done in UTC time. Is this also the case for this example and should I add something else to do it in Berlin time?
Ultimately I would like to know if there is a "cleaner" way to accomplish this specific rounding with only dateutils onboard tools? I would like to leave out the command substitution "$(date +'%FT%T')"
.
You mentioned that the rounding is done in UTC time. Is this also the case for this example and should I add something else to do it in Berlin time?
Yes-ish. A timestamp in dateutils as such is zone-less, by which I mean it doesn't carry a timezone designation (as in, say, the SQL type DATETIMEOFFSET or DATETIMETZ). So if you feed it a textual string dateutils is just doing its thing but if you invoke timezone stuff (--zone for instance), it's going to assume the timestamp is UTC (or sometimes TAI) by default. You can even change this assumption using --from-zone.
Ultimately I would like to know if there is a "cleaner" way to accomplish this specific rounding with only dateutils onboard tools?
I already showed you. You could do:
$ date +'%FT%' | dround 00s42m00h15d
using pipes, and the "zoned" timestamp in ISO8601 format. Or if you want it in Berlin time explicitly anywhere in the world:
$ dconv now -z Europe/Berlin | dround 00s52m00h15d
dateutils allows reading timestamps from stdin if not specified. The output shall be exactly what you want. The only caveat of not being aware of the timezone is that you may round to forbidden or ambiguous timestamps. Berlin time (currently) has an hour missing in March (never on the 15th though), and a duplicate hour in October (also currently never on the 15th).