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

ZonedDateTime should expose its 'fold' and 'is_ambiguous' properties in some way #68

Closed
bxparks opened this issue Feb 25, 2024 · 2 comments
Labels
discussion Discussion is needed before proceeding documentation Improvements or additions to documentation in development Has been addressed but not released yet

Comments

@bxparks
Copy link

bxparks commented Feb 25, 2024

As far as I can tell, ZonedDateTime, which inherits from DateTime AwareDateTime time, does not expose the underlying fold value:
https://whenever.readthedocs.io/en/latest/api.html#whenever.ZonedDateTime
https://whenever.readthedocs.io/en/latest/api.html#whenever.AwareDateTime

It may not be obvious that the fold parameter described by PEP 495 is both an input parameter and an output parameter. The output fold parameter is what allows datetime.datetime to support round trip conversions without loss of information. In other words, epoch_seconds can be converted into datetime.datetime, which can then be converted back to epoch_seconds, and the 2 epoch_seconds will be identical, even during an overlap (when, for example, northern hemisphere countries "fall back" in the fall).

But more practically, the fold parameter of a datetime.datetime object is useful to a client app, because it allows the app to know if a specific epoch_second was converted to a datetime which could be interpreted by humans as ambiguous. Access to the fold parameter is required if the application wants to warn the user of an ambiguous time, something like: "The meeting time is 01:30 on Nov 3, 2024 (Warning: this is the first occurrence of 01:30, not the second occurrence.)"

Currently, ZonedDateTime is a thin wrapper around datetime.datetime. But it does not expose the fold parameter to the calling client. I think it should, but in a way that is more friendly than fold. As I was writing this ticket, it occurred to me that there is a complication: the underlying datetime.datetime class, which is used by ZonedDateTime, does not actually contain enough information to solve this problem properly. We actually needZonedDateTime to expose two bits of information:

  1. is_ambiguous: bool: Whether or not the epoch_seconds mapped to a ZonedDateTime that can be ambiguous, i.e. a "duplicate" or an "overlap". Alternative names for this property may be is_overlap or is_duplicate.
  2. fold: int: 0 if the ZonedDateTime corresponds to the first instance, and 1 if the ZonedDateTime corresponds to the second.

The is_ambiguous parameter can be calculated by brute force within ZonedDateTime. But it would be more efficient to delegate that calculation to a TimeZone class (which does not currently exist in whenever, but I described its contours in #60), so that we get efficient access to the metadata information about the given timezone.

Anyway, I don't know how you want to prioritize this issue. I figure that if you are going make a clean break from datetime, and solve a bunch of problems, you might as well fix this one too. :-)

@ariebovenberg
Copy link
Owner

ariebovenberg commented Feb 25, 2024

Interesting.

For detecting ambiguity, there already is a disambiguated() method that checks if a time can be considered ambiguous. In 0.4 it will be renamed to is_ambiguous()

Regarding exposing the fold value: in the current version, ZonedDateTime does expose a fold attribute, it just is mistakenly undocumented. However, I will be removing it in version 0.4 because no other language I know of stores the disambiguation: the standard seems to be storing the offset instead.
As an alternative, perhaps something like disambiguation() can be added later, which returns an enum like NOT_AMBIGUOUS | EARLIER | LATER or something...

also: I also wish that ZoneInfo objects themselves had methods like is_ambiguous...

@ariebovenberg ariebovenberg added discussion Discussion is needed before proceeding in development Has been addressed but not released yet documentation Improvements or additions to documentation labels Feb 25, 2024
@ariebovenberg
Copy link
Owner

is_ambiguous() is now part of ZonedDateTime as of 0.4. The foldattribute is considered an implementation detail and can be retrieved from the underlying datetime withdt.py_datetime().fold`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Discussion is needed before proceeding documentation Improvements or additions to documentation in development Has been addressed but not released yet
Projects
None yet
Development

No branches or pull requests

2 participants