Readit News logoReadit News
Hasnep · 8 months ago
If you've not read the blog post that explains why this library exists I recommend it. It's called "Ten Python datetime pitfalls, and what libraries are (not) doing about it"

https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls...

jwilk · 8 months ago
Discussed on HN back then:

https://news.ycombinator.com/item?id=39417231 (147 comments)

barbazoo · 8 months ago
I am a seasoned programmer but whenever I deal with datetime objects I do my best with unit tests and then just hope none of these “edge” cases apply to us. Meaning: I have no idea really how it works under the hood.

Now at least there’s an LLM that might spot a bug every now and then so that’s nice.

Deleted Comment

JodieBenitez · 8 months ago
Excellent read.
wesselbindt · 8 months ago
Ah nice it solves the Liskov violation that the standard library has. In the standard library, dates can be compared with <, and datetimes are dates. But compare a datetime with a date with <, and you get an error. This drove me nuts at work recently.

I wonder what benefits this choice has that outweigh the risks of this behavior.

OJFord · 8 months ago
What would you do about equality comparisons?
scott_w · 8 months ago
The author wrote a blog post describing that the problem is datetime inherits from date when it shouldn’t. The fact they do but can’t be compared is a compounding of the problem with hidden bugs
heavenlyblue · 8 months ago
What do you expect? There are so many ways to handle this behvaiour it's pretty obvious why this is not allowed. Do you take datetime.date and then compare? Do you assume all dates are datetimes at midnight?
MrJohz · 8 months ago
The issue isn't that the comparison should be valid, the issue is that datetimes should not be dates. At best, there is a "has a" relationship, but there shouldn't be an "is a" relationship.
pkkm · 8 months ago
I think wesselbindt meant that datetimes should not inherit from dates.
JimDabell · 8 months ago
I’ve tried Arrow, Delorean, and Pendulum, plus the stdlib datetime of course, and settled on Whenever. It fits what I actually do with datetimes better, plus it seems more actively maintained. With the others I always seem to have a nagging feeling in the back of my mind that I am missing a whole load of edge cases. With Pendulum that seems more baked into the API.
mixmastamyk · 8 months ago
Sounds like we need an industry/language-wide test suite to check these many date/time/calendar libraries against. Like the browser acid tests, though focused to baseline functionality only.

https://en.wikipedia.org/wiki/Acid3

I like this new lib (Thank You) but the name unfortunately implies the opposite of what it is. "Whenever" sounds like you don't care, but you'd only be using this if you did care! Also Shakira, haha. Hmm, pedantic is taken. Timely, precise, punctual, meticulous, ahorita, pronto, etc. I like that temporal name.

Finally, none of these links mention immutability, but it should be mentioned at the top.

mdaniel · 8 months ago
Without the slightest sense of irony, I actually strongly suspect such a test suite would only be valid at one moment in time, since the timezone legislation is almost continuously in flux. That's why <https://www.iana.org/time-zones> and its friend <https://www.oracle.com/java/technologies/javase/tzupdater-re...> exist. As if to illustrate my point, the latest update was 2025-03-22, presumably nuking any such conformance test from Mar 21st
NeutralForest · 8 months ago
In that case, you'd have unit tests that confirm behaviors like compatibility or failure of some operations between types and integrations tests which pull an up to date DB of rules and tests against that.
mixmastamyk · 8 months ago
It would have to take the real world into account, no? Additionally it could test various timezone definition permutations without necessarily being dependent on a real one.
apeters · 8 months ago
Am I the only one to stick with the std lib, read the docs and changelogs carefully, and implement functions I really need the way my application makes use of them?

I learned the hard way, that dependencies kill projects.

Not saying this isn't great, thanks for creating it! It does have its use cases, of course.

stavros · 8 months ago
> Am I the only one to stick with the std lib, read the docs and changelogs carefully

I work in healthcare. If I have a choice between "reading docs/changelogs carefully, implementing functions", and "adding an extra dependency", I'm taking the dependency every single time.

I don't want footguns in my code, I don't want code I have to write and test myself, and I don't want to have to become an expert in a domain before I can write something that serves my purpose.

For the datetime library, specifically, I'm switching to whenever for everything, because I've been bitten by conversions and naive/aware datetime confusion too many times.

jethkl · 8 months ago
My hope is that a lib like this one or similar could rally mindshare and become integrated as the new standard, and adopted by the wider developer community. In near term, it comes down to trade-offs. I see no decision that works for all use cases. Dependencies introduce ticking time bombs, stdlibs should be correct and intuitive, but at least when not they are usually well tested and maintained, but when stdlib don't meet urgent production needs you have to do something.

Link to Tom Scott & Computerphile from 10y ago on tz madness. https://www.youtube.com/watch?v=-5wpm-gesOY

globular-toast · 8 months ago
> I work in healthcare. If I have a choice between "reading docs/changelogs carefully, implementing functions", and "adding an extra dependency", I'm taking the dependency every single time.

This kinda sums up the sorry state of software engineering. People can't even be bothered to read docs but will just blindly install a package just because someone was able to package it and upload it to PyPI.

Taking on a dependency does not relieve you of reading docs, but it also adds a further burden as you now need to trust the code. The stdlib is much more heavily tested and documented than any 3rd party library will be.

barbazoo · 8 months ago
I get where you’re coming from. There’s a price you pay though eventually. You’ll have to thoroughly vet all your dependencies for malicious code at some point. Otherwise how do you have any clue what you’re running?
EdwardDiego · 8 months ago
There are so many footguns in the datetime lib.

That's why I use a Flake8 plugin to prohibit especially egregious footguns.

https://github.com/jkittner/flake8-ban-utcnow

raverbashing · 8 months ago
Honestly yeah who in tarnation created that function and called it utcnow

These things are really frustrating

sgarland · 8 months ago
You are a sad minority, IME. I’m right there with you. I extended the uuid library to generate UUIDv7, based off of the RFC. It’s pretty easy to implement, as it turns out. Overruled, because “we don’t want to have to maintain additional code.” As if the ABI for bitshifts is going to change?!
ljm · 8 months ago
There’s an out of sight, out of mind mentality with dependencies.

As long as there is a conscious decision to build or ‘buy’, it’s fine. I think some people can be a little too careless with adding dependencies though, not realising they can have an equal if not greater maintenance burden.

foolfoolz · 8 months ago
this is a great idea if you want to slow down your project. most projects start with few rules and “best practices” like this. everyone is free to pull in dependencies as needed. because they are needed. but then once the project grows larger, those who have been around longer want to reverse course and gatekeep dependencies. but this is the opposite of what helped the project grow initially. and later contributors have a harder time making similar progress because they have to fight to add basic libraries. ensuring that efficiency per engineer goes down
johnfn · 8 months ago
I think this is fairly unrealistic. Does all your datetime manipulation involve proper use of the fold parameter as indicated in the article?
mr_mitm · 8 months ago
Are you saying you never pull in dependencies? Why stop there, why not re-implement the std lib as well? Surely there is a sensible middle ground: If you only need a small part of a dependency, consider implementing it. If you make heavy use of a dependency and want to benefit of years if not decades of dedicated developers testing and maturing its code, with a large community who has already stepped in all pitfalls you might step into and collectively encountered all the edge cases, just use the dependency.
xandrius · 8 months ago
Creating from scratch also creates hidden debt, it's just moved onto yourself. Especially when working with dates and timezones.
brookst · 8 months ago
I cannot imagine having the spare time to invest in building date/time foundations and maintaining them through changes to DST timing and country/time zone changes.

The only crazier idea I can think of is implementing character encoding conversions myself.

raverbashing · 8 months ago
A library that goes "poof" when you need to upgrade it is also a hidden debt
BiteCode_dev · 8 months ago
Functions that you have to document, test and maintain of course. You do that, right? And all the people in your team, they do that and will keep doing that once you leave, right? And they all understand the business domain and all the pitfalls that come with it and have the skill, time, and resources to take care of it, right?

And this for every single problem: time, text, maths, network, parsing, formatting, validating, authenticating...

dmos62 · 8 months ago
Curious about examples of projects being killed by dependencies.
michaelt · 8 months ago
While I've never seen a project killed by dependencies, I've certainly seen projects stuck on treadmill of constant dependency updates.

You know, they import 5 libraries, each of which imports 5 more libraries, each of which imports 5 more libraries, and suddenly they're buried in 'critical' updates because there's a denial-of-service bug in the date parser used by the yaml parser used by the configuration library used by the logging library used by the application.

ljm · 8 months ago
Not killed IME but bloated and dragged down by tech debt.

E.g the JS project that uses the stdlib Date API, and pulls in moment.js, and also uses date-fns.

Or the one that pulls in bits and pieces of lodash, ramda, and other functional libraries.

And maybe it uses native fetch and axios depending on the current phase of the moon.

They don’t die but time is wasted in code review trying to understand if there is any kind of deliberate approach behind the scattershot application of packages with duplicated purposes.

(picking on JS is perhaps unfair but it’s probably the most egregious example of dependency hell)

pkkm · 8 months ago
I'm not the creator, the credit for that goes to Arie Bovenberg. I just wanted to show this to people.
mvanbaak · 8 months ago
As others stated, there are many rough edges and footguns in the stdlib. BUT ... in my (and yours apparently) opinion, it's a matter of knowing those edges/guns, and work with them. Like you, I also prefer to create my own code around those instead of bringing in some library that brings in their own foot guns and possibly sub-dependencies and and and...
matsemann · 8 months ago
So your projects end up with their own "lib" of scattered time functions, possibly with new small bugs. I'd then rather have a proper well-tested and maintained library.
Kwpolska · 8 months ago
> available in Rust or pure Python.

Hard pass. The complexity of having to use binary packages or build things is not worth the performance benefit. The pure-Python version requires building from source and passing special flags, so it is not possible to specify it in requirements.txt.

stavros · 8 months ago
That seems like an easy fix, they could release it as `whenever[pure]`. It would probably take less time to write up the issue than to write your comment.
Kwpolska · 8 months ago
Extras only affect dependencies, you can’t have different codebases for them.

An issue was closed as not planned: https://github.com/ariebovenberg/whenever/issues/158

BiteCode_dev · 8 months ago
Ah, so you are not using pyQT, numpy, any database driver, pillow or anything using cryptography, then?
Kwpolska · 8 months ago
For the libraries you listed, the benefits of using a native library are much larger, since they’re wrapping a well-known library that is known to be secure and fully-featured, or since the performance benefits are actually visible in any significant code snippet. But here, there is no Rust library to wrap, and I doubt the performance of a date-time library would have any effect on the performance of virtually all applications (maybe except for calendar apps).
OJFord · 8 months ago
> The pure-Python version requires building from source and passing special flags, so it is not possible to specify it in requirements.txt.

You can put any flags in requirements.txt, including -r[equiring] another txt etc.

Your point may apply to modern pyproject.toml tooling though, or at least that it wouldn't be simply another entry in the dependencies array.

Kwpolska · 8 months ago
The special flags are environment variables, you can’t pass that in requirements.txt: https://whenever.readthedocs.io/en/latest/faq.html#how-can-i...
kelseydh · 8 months ago
A big revelation for me in solving so much timezone insanity came from realising that timezones should be expressed as locations rather than zones.

Avoid general terms like "Pacific Standard Time" and stick to location-specific ones like: "Vancouver/Canada". The latter is how people expect their time to work, and correctly handles whatever quirky choices jurisdictions choose to do with their time.

throwaway2037 · 8 months ago
In my experience, all worthy date/time libraries use time zone IDs from the "tz database". Ref: https://en.wikipedia.org/wiki/Tz_database

Searching the list here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

I cannot find an entry for "Pacific Standard Time" nor "Vancouver/Canada", but I can see: "America/Vancouver".

JimDabell · 8 months ago
The rule of thumb is: Use UTC to record when things happened (e.g. logging), use local time + timezone name (e.g. `Europe/London`) to schedule things for the future (e.g. meetings).
wodenokoto · 8 months ago
Funny it doesn’t add comparison to date times in pandas, which is probably used to handle more dates than any of the others.
jiggunjer · 8 months ago
Pandas uses stdlib or numpy for it seems.