4 ms·
First, I can see some benefits to a false midnight. The case of truncated timestamps discussed on the Python list is actually useful. However, the problem wit
by einhverfr 13y ago
First, I can see some benefits to a false midnight. The case of truncated timestamps discussed on the Python list is actually useful.
However, the problem with the Python truth value of a date here goes way deeper than what folks have generally discussed and make the behavior here unsafe for any use.
When designing a module, contracts are important. You don't want to ever have to break a contract if you can avoid it. Sometimes it will be unavoidable, but you hope not. What this means is that your contracts need to be clear, precise, and meaningful, and the code needs to implement the contract.
I good contract would have read something like:
A time value is false if it represents a midnight, either when unqualified by timezone or when midnight GMT.
This gives you a specification. It gives you something you can use and count on. Maybe it is a killer feature for someone. However the implementation instead was:
A time value is false if and only if it evaluates to zero after subtracting the timezone offset if it has one.
Think about what this means when you have a negative vs a positive offset. It means that negative timezone offsets allow a date to always be true, but positive ones allow it to be false at UTC midnight. The real takeaway from this really should be the fact that API documentation should be declarative in nature and not procedural. Don't tell me how you get an answer. Tell me what the answer means. if you do the latter, then nothing can ever be fixed but probably cannot be safely used either.
The problem then is first and foremost a problem of API design and a design which is fundamentally flawed. This is why absent where the algorithm is critical to the contract it should not be mentioned. Explain what is expected and what it means, not how you get at the answer.
- jessaustin 13y ago...negative timezone offsets allow a date to always be true, but positive ones allow it to be false at UTC midnight. I haven't had my tea yet, but is this true? ISTM that if a positive offset can be false in the AM, a negative one might be false in the PM.
- plorkyeran 13y agoThe actual check is for if time_in_minutes == tz_offset_in_minutes. The problem is that times are always positive, so this check doesn't work if the offset is negative. The correct implementation would be time_in_minutes == (tz_offset_in_minutes + minutes_in_day) % minutes_in_day.
- jessaustin 13y agoThanks for the info. I've confirmed this for myself now: class Offset(tzinfo): def __init__(self, offset): self.offset = offset def utcoffset(self, dt): return self.offset >>> bool(time(1, 0, tzinfo=Offset(timedelta(hours=1)))) False >>> bool(time(23, 0, tzinfo=Offset(timedelta(hours=-1)))) True Although this is kind of funny, because for time.hour, 23 and -1 should be the same thing: >>> bool(time(23, 0, tzinfo=Offset(timedelta(hours=23)))) False I'm convinced: legacy behavior is wrong and should be changed.
- wdewind 13y ago> First, I can see some benefits to a false midnight. The case of truncated timestamps discussed on the Python list is actually useful. Can you expand on this, I don't understand (didn't read the list). Couldn't you just test for the actual time instead of a boolean if you are trying to do something at midnight?
- einhverfr 13y agoOk. So suppose you have feeds of data that lead into your database. These come from various sources and some of the feeds go through different pathways in processing before being entered. Let's say that for some hypothetical legitimate reason some feeds are truncated to the date. These all get stored as timestamps in your database. Now many db's (maybe even most) will happily cast dates to timestamps, but they do this by filling in 00:00:00 for the time. If you have to special case these in your front end, being able to treat truncated datetimes as having no date could be quite helpful. Now this would not be an ideal design, I think we'd all agree. It would be very remotely possible a date could be 00:00:00.000000 in time and so you'd have some false positives. Ideally we'd put a flag on the record to say the date had been truncated, but you know, there are always cases where legacy code gets in the way of sane fixes. In an ideal world this might never be a useful feature. In the real world I could imagine a number of uses in working around systems which one cannot reasonably safely or easily modify. Yes, you could special case check for midnight. But there are cases where "midnight is false" happens to correspond to actual behavior elsewhere.
- jrochkind1 13y agoNope, there are standard arithmetic rules for subtracting negative numbers: `3 - (-3) == 0` Your two versions of the contract mean the same thing, and I am confident it is implemented such. I agree with you that the actual wording is sloppy and confusing, and your version would have been more clear. But they mean the same thing.
- einhverfr 13y agoI don't know where you learned arithmetic, but where I learned it, 3 - (-3) == 6.... What this means effectively is that 1am GMT+1 would evaluate to false, but 11pm GMT-1 would evaluate to true because 23:00 + 1.00 == 24:00, and 24 != 0.
- jrochkind1 13y agooops, my arithmetic was wrong, but my point was right... I think? If it's 21:00 in a timezone that's GMT-3, you take 21:00 - (-3) and get 00:00, the correct GMT time. No? Oh, I see your point, it says nothing about rollover. Okay, I dunno. Times are confusing.