Hacker News new | ask | show | jobs
by ariebovenberg 859 days ago
I wouldn't consider 'not handling leap seconds' as a pitfall. If you need to account for leap seconds, you're probably not going to use a general-purpose datetime library.

Unix time ignores leap seconds, so does RFC 5545 (iCal), and most modern libraries (Chrono, Temporal, NodaTime).

1 comments

You need to account for leap seconds literally any time you are mixing durations/timedeltas with instants/datetimes, otherwise you will get wrong answer. Also needed whenever you parse ISO8601/RFC3339 style strings. For example this (correct) timestamp fails to parse:

    >>> UTCDateTime.from_rfc3339('1998-12-31T23:59:60Z')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/tmp/tmp.4kBsq6IYyF/venv/lib/python3.11/site-packages/whenever/__init__.py", line 797, in from_rfc3339
        return cls._from_py_unchecked(_parse_utc_rfc3339(s))
                                      ^^^^^^^^^^^^^^^^^^^^^
      File "/tmp/tmp.4kBsq6IYyF/venv/lib/python3.11/site-packages/whenever/__init__.py", line 2420, in _parse_utc_rfc3339
        return _fromisoformat(s.upper())
               ^^^^^^^^^^^^^^^^^^^^^^^^^
    ValueError: second must be in 0..59
I do point out that if your internal representation would be simple naive epoch+duration(/timedelta) then you don't need any special accounting for leap seconds when doing time arithmetic like this. The problem arises only if you are trying to be somehow clever with your internal representation (and failing).
You are correct that there are improvements to be made. The current internal representation is—for the moment—simply the Python standard library.

Probably the approach of Chrono is best: allow leap seconds to be represented (i.e. 23:59:60), but not to account for them historically.