4 ms·
Across all languages, what are the best libraries, with least amount if pitfalls? (java.time seems good, anything even better elsewhere?)
by falserum 3y ago
Across all languages, what are the best libraries, with least amount if pitfalls?
(java.time seems good, anything even better elsewhere?)
- assbuttbuttass 3y agoI really like Go's "time" package. The only pitfall I can think of is that it doesn't really handle overflow at all. https://pkg.go.dev/time https://pkg.go.dev/time
- rad_gruchalski 3y agoAnd date time parsing sucks with its predefined mask elements.
- pgwhalen 3y agoGo's time package seems like one of the bad ones, since it makes the classic mistake of combining zoned and naive times into the same type (arguably it doesn't support naive times at all).
- zokier 3y agojava.time doesn't handle leap seconds very well :( jshell> ChronoUnit.SECONDS.between(Instant.parse("1974-01-01T00:00:00Z"), Instant.parse("2024-01-01T00:00:00Z")) % 86400 $22 ==> 0 astropy gets you the correct answer: >>> from astropy.time import Time >>> (Time('2024-01-01T00:00:00Z') - Time('1974-01-01T00:00:00Z')).sec % 86400 24.0 of course astropy is bit specialized and not really something I'd use as general purpose date/time library. But this is one good litmus test for datetimes, feel free to try it with your favorites.
- zokier 3y agoI tested this with the library from TFA, and it fails too :( >>> from whenever import UTCDateTime >>> (UTCDateTime(2024, 1, 1) - UTCDateTime(1974, 1, 1)).total_seconds() % 86400 0.0
- DandyDev 3y agoWhat does TFA mean here? Trifluoroacetic Acid?
- ariebovenberg 3y agoAuthor here— This is a conscious decision, I'll explicitly address this in the FAQ soon. As I commented elsewhere, this is completely in line with industry standards (iCal, Unix time) and other modern libraries. I don't (yet) see any reason to deviate.
- ariebovenberg 3y agoI 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).
- zokier 3y agoYou 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
- zokier 3y agoI 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).
- ariebovenberg 3y agoYou 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.