[Python-Dev] datetime +/- scalars (int, long, float)? (original) (raw)
Guido van Rossum guido@python.org
Tue, 05 Mar 2002 14:25:44 -0500
- Previous message: [Python-Dev] datetime +/- scalars (int, long, float)?
- Next message: [Python-Dev] datetime +/- scalars (int, long, float)?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
> [MAL] > You should forget about DST if you want a sane > implementation. Same for leap seconds.
[Kevin Jacobs]
My datetime objects manage these complexities by layering their implementation. Our base class stores a time since epoch and a timezone offset. It implements all the arithmetic functions based on 1day=24hours and has methods that re-normalize the timezone to a fixed offset after every modifying operation. It also has a translate(tzoffset) function that returns the an adjusted time since epoch with a different timezone offset. This way, our client applications never deal with DST or timezone changes unless they request it.
You can try to hide from DST, but you can't run. It always shows its ugly head when you lift the next stone, just as you least expected it.
I'm thinking of a layered implementation myself, and I think some big changes to the datetime.py prototype will be necessary. I'm thinking that for most business uses of date and time, we should have the same attitude towards DST that we've already decided to take towards leap seconds. If I move an appointment that's scheduled for 12 noon today and move it a week ahead, it should still show up at 12 noon, even if the DST changes in between.
I think I want to introduce a new concept, closely related to local time, that I'll dub "naive time" for now. In naive time, there is no timezone and there is no DST. To compensate for DST, you have to manually change the clock, which is an action outside the system, unknown to the system, and irrelevant to the working of the system. Ditto to change time zones.
Naive time is what you see on your watch or your Palm organizer (apparently not on PocketPC or Windows/CE though, which are timezone aware). A day is always 24 hours, and the clock always shows local time. When the DST jump happens, you lose or win an hour but you do your best to pretend it didn't happen, by going to bed a little earlier or by partying a little longer (or any other activity that causes memory loss :-).
My Palm has no problem keeping track of appointments in different timezones: when I have a meeting in San Francisco at 11am, I enter it at 11am, and when I fly there, I move the Palm's clock three hours back. Naive time adapts to local time -- time flies (or stands still) when you're in an airplane crossing timezones.
Naive time calculations are easier than local time calculations, because they don't have to worry about DST. You only have to be careful when converting between naive time and UTC (or anything else that has a concept of timezone).
Which brings us to...
For calculations that require DST awareness, of which there are a surprising number, we have a datetime sub-class that adds two extra modes:
1) Fixed tzoffset (from base datetime) 2) Fixed tzoffset +/- fixed DST adjustment based on current time since epoch (folds in to case 1 after initialization) 3) Fixed tzoffset +/- dynamic DST based on stored time since epoch (dynamically updates after every mutating date operation)
I'm not sure exactly what these mean yet, but by the time I've implemented the new regime in datetime.py, I expect I will. :-)
I'm very tempted to put all the smarts in conversions though: you can take a naive datetime object, interpret it in a particular timezone using a given DST ruleset (local time and UTC being two common cases) and convert it to a timestamp, which has different semantics, but can be converted back to naive time by interpreting according to some timezone.
> If someone wants DST and timezone aware time differences, > then this is a completely different concept than taking the > difference w/r to number of days.
Precisely. Our implementation is sub-optimal in that it can do roughly twice as much work as necessary at times. This is because we layer the DST adjustments on top of the datetime object. The advantage to this approach is that the code is very cleanly segregated between DST agnostic code and DST pathological code.
And that's what I want too.
> Just to hint at another problem: you sometimes want to > know the time difference of two dates in terms of > years, months, days, hours, etc. that is, you are not > interested in 86400 second days, but in calendar days > or even months. For months you'll run into problems > with non-existing days, e.g. for 2002-03-31 - 1 month.
We handle these cases with a business logic layer on top of the DST aware datetime object. It handles exceptions thrown, like BeyondEndOfMonthError, and takes the appropriate action. In the case of BeyondEndOfMonthError, the typical resolution is to set the day to the last day of the month.
Good idea. This can probably be remain implemented in Python.
--Guido van Rossum (home page: http://www.python.org/~guido/)
- Previous message: [Python-Dev] datetime +/- scalars (int, long, float)?
- Next message: [Python-Dev] datetime +/- scalars (int, long, float)?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]