Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is dround bugged or just confusing? (now with specific timezone) #158

Open
Git-Boy-Slim opened this issue Apr 11, 2024 · 3 comments
Open

Comments

@Git-Boy-Slim
Copy link

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.

@hroptatyr
Copy link
Owner

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.

@Git-Boy-Slim
Copy link
Author

Git-Boy-Slim commented Apr 11, 2024

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')".

@hroptatyr
Copy link
Owner

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants