Hacker News new | ask | show | jobs
by guitarnick 858 days ago
The author provides this example to illustrate inconsistent handling of non-existent datetimes:

    # This time doesn't exist on this date
    d = datetime(2023, 3, 26, 2, 30, tzinfo=paris)

    # No timestamp exists, so it just makes one up
    t = d.timestamp()
    datetime.fromtimestamp(t) == d  # False
Criticisms:

1) The example would fail just as well for any datetime with given tzinfo. Because fromtimestamp returns native datetimes.

2) The timestamp isn't just "made up". Its behaviour is clearly documented in PEP 495, as linked by the author [0]. In this case it consistently corresponds to datetime(2023, 3, 26, 3, 30, tzinfo=paris).

[0] https://peps.python.org/pep-0495/

Finally if we disallow creating non-existent datetimes in the proposed library, how do we represent the 2am in "clock changes forwards at 2am"? Use 3am? There are tradeoffs.

2 comments

Author of the blog post here—

1) You're absolutely right, I'll fix this mistake in the example.

2) "Made up" was perhaps stirring the pot too much ;), but the fact remains that a timestamp is created when one essentially doesn't exist. That this is meticulously documented in PEP495 doesn't change this fact.

Note that PEP495 also explicitly describes some of the other pitfalls. Documenting a 'suprise' is not the same as eliminating it.

> Finally if we disallow creating non-existent datetimes in the proposed library, how do we represent the 2am in "clock changes forwards at 2am"? Use 3am? There are tradeoffs.

Indeed, there are always tradeoffs. Often, only time can tell what was the 'least bad' decision. It is telling though that modern datetime libraries (Noda Time, Chrono, Temporal) in other languages choose to not represent these 'missing' local times.

I must add that I do appreciate you challenging the status quo. Excited to see where your library leads.

> modern datetime libraries … in other languages choose to not represent these 'missing' local times.

Another edge case with throwing errors over gap times is eventually a region’s dst policies may change. So what used to be valid can now be invalid (and vice versa). Updating the library must be done with an audit of existing data, or suffer loud unexpected failures.

Thanks for taking the time to address this critic. Easier to be a critic than a creator after all.

Indeed, structural changes to timezones also need to be handled. Temporal has a good approach here https://tc39.es/proposal-temporal/docs/ambiguity.html#ambigu....

Basically:

- Store the offset and the tz ID

- When deserializing, allow explicit choice what to do: keep the offset (i.e. same moment in time) or keep the local time (i.e. same time on the 'wall clock')

> Documenting a 'surprise' is not the same as eliminating it.

I'm going to have to remember that one

> Documenting a 'suprise' is not the same as eliminating it

I'd go as far as saying documenting a surprise is basically having a bug and writing "won't fix".

> only time can tell

I see what you did there.

> how do we represent the 2am in "clock changes forwards at 2am".

If we are willing to adjust a tiny bit, there are options:

Option1: “01:59 is followed by 03:00”.

Option2: “clock changes forwards at 2am GMT+2” (GMT+2 is offset before the hour jump)