11 ms·
Am I the only one who would expect the behavior in the top example? I don't want my equality operator doing timezone conversions. If one type has no timezone a
by nly 4y ago
Am I the only one who would expect the behavior in the top example?
I don't want my equality operator doing timezone conversions. If one type has no timezone attached and one does, then you probably shouldn't be able to compare them at all. Likewise, for a type that has a timezone attached, if the timezone differs between a and b, then I want a == b to return false, even if it represents the same instant in time.
Equality can be a tricky thing. Named functions are the way to go when two different developers might intuit different behaviors.
- stavros 4y ago> Likewise, for a type that has a timezone attached, if the timezone differs between a and b, then I want a == b to return false, even if it represents the same instant in time. Really? So if you want to compare that two times are really the same time for two different timezones, you'd want to convert them to UTC first? What's the use case for this? Seems like the less-used way to me.
- nly 4y agoYou don't need to convert them to UTC, just one to the timezone of the other, but yes. "a.is_same_instant(b)" is a lot more clear to me than "a == b", especially in a dynamic language where it might not be obvious what the types involved are.
- stavros 4y agoHm, I don't know, I guess == on datetimes means "is the same instant" to me.
- rzzzt 4y agoNoone else has to guess (or go and inspect what an overloaded comparison operator actually does) if there is a meaningful name attached to the comparison, like in the parent comment.
- stavros 4y agoSure, but there's also a reason we don't have `x.is_numerically_equal_to(3)`.
- fdupress 4y agoAnd that reason is that there is a canonical definition of what it means for two numbers to be equal. The fact that your intuition of "these two timestamps are equal" is "these two timestamps denotes the same instant" seems problematic when we know that the notions of timestamps and time are not in fact aligned (because, for example, of leap seconds).
- ur-whale 4y agoThat's what it means to you But an API should never get into a place where your personal choices should matter and various incompatible interpretations potentially make sense to different people.
- raverbashing 4y agoThis sounds like turning a good API into an unreadable mess. And no, it is not pythonic No, most people do want to compare times in different TZs without the extra cruft.
- sanderjd 4y agoIt would be turning a really bad API that is a constant source of errors into a slightly better and less error prone API. It's totally possible that "pythonic" means "error prone", but that would not be something to tout proudly if so. I think a better API would be to have a different types for timezone- naive vs. aware datetimes, and a canonical way to convert either of those types into an instant in time (requiring a timezone be attached for the naive type). Then the instants in time could be compared with the equals operator without confusion.
- raverbashing 4y ago> It's totally possible that "pythonic" means "error prone" Those who say that don't know what it means. And given how much I have to deal with crap APIs that disregard those principles it's safe to ignore discussions leading elsewhere
- sanderjd 4y agoOk, let me take this a bit more seriously. What "pythonic" principles does the existing API maintain that the proposed "crap API" disregards?
- stingraycharles 4y agoThe problem is not that the equality behavior is wrong, it’s that I would expect “utcnow()” to return a timestamp with a UTC timezone. The problem is that it does not, it has no timezone at all, and therefor is generally less compatible than creating a timestamp with timezone from a utc timezone object. I work on the Python API of a timeseries database and it’s very frustrating to have to accept timestamp objects without time zone because you don’t know what to do with them. People aren’t aware of this constraint, which leads to unexpected behavior.
- BiteCode_dev 4y agoDjango solves this by having the default timezone in the framework settings. Any datetime without a timezone is assumed to be using the default one. If you don't set a default timezone, the server timezone is used, and you are responsible for making sure your data is congruent.
- stingraycharles 4y agoYes I know, but that doesn’t help pretty much any of our Python users that are all heavily reliant on Pandas and/or definitely not writing web services. As of now, we just reject any timestamp without an explicit timezone and try to explain to our users why utcnow() is bad. People are generally very surprised that this issue exists at all.
- BiteCode_dev 4y agoYeah naive datetime should not even exist in high level API IMO. They're like bytes string with no encoding or geospatial data without a projection name field. It's going to bite you at some point.
- tpoacher 4y agoTimestamps do not have timezones. That's the whole point of a timestamp.
- 4y ago
- slooonz 4y ago> I don't want my equality operator doing timezone conversions Nobody argues for that. Especially since we’re comparing timestamps (floats), not datetimes (objects). Let’s go line by line : > ts = 1571595618.0 This is 2019-10-20 18:20:18.000 UTC > x = datetime.utcfromtimestamp(ts) I would therefore expect x to be 2019-10-20 18:20:18.000 UTC > x_ts = x.timestamp() I would therefore expect x_ts to be 1571595618.0. Which is surprisingly not. Nowhere the equality operator was involved in the surprise.
- nly 4y agoThe comparison is being done between x_ts, which is a float, and x, which is a datetime object. Call be crazy but I think allowing this comparison to begin with is the problem. >>> from datetime import datetime >>> ts = 1571595618.0 >>> x = datetime.utcfromtimestamp(ts) >>> x_ts = x.timestamp() >>> type(x_ts) <class 'float'> >>> type(x) <class 'datetime.datetime'>
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- TotempaaltJ 4y agoThe code in the first example says `ts == x_ts`, not `ts == x`.
- nly 4y agoArgh.
- anttihaapala 4y agoThat's not the code from the article. The code in the article is comparing 2 floats. Though, equality operator would return `False` for comparison `x == x_ts` as well, instead of throwing an exception.
- 4y ago
- deleted 4y ago[deleted]