There's a problem with strftime() in DateTime.py. Try this DTML method to see: ---- <dtml-var standard_html_header> <dtml-let time1="_.DateTime('2000/07/23 BST')"> Time: <dtml-var time1> <br> Time: <dtml-var time1 fmt=Date> <br> Time: <dtml-var time1 fmt="DayOfWeek"> <br> Bad Time: <dtml-var time1 fmt="%a, %d %B %Y %Z"> <br> Time: <dtml-var "time1.fCommonZ()"> <br> </dtml-let> <dtml-let time1="_.DateTime('2000/07/23 GMT')"> Time: <dtml-var time1> <br> Time: <dtml-var time1 fmt=Date> <br> Time: <dtml-var time1 fmt="DayOfWeek"> <br> Time: <dtml-var time1 fmt="%a, %d %B %Y %Z"> <br> Time: <dtml-var "time1.fCommonZ()"> <br> </dtml-let> <dtml-var standard_html_footer> ---- Note that the time given in the line "Bad Time:" above is actually wrong -- it reports itself to be in GMT, but gives the time as one hour behind. If you specify a date as YYYY/MM/DD, then the date that is stored is (quite reasonably) midnight on that day, in your timezone. This gets rendered back into days correctly for methods such as DateTime.day(), as these methods directly ask the DateTime instance for what it thinks the day is. The instance replies in the context of its own timezone (as given in the constructor, or the local timezone if none was given), and so it returns the expected result. If you use the strftime() method, by using fmt="%d %H %Z" or whatever, instead of asking the DateTime instance to do the formatting, the formatting is delegated to the Python time module. Unfortunately, at any particular time, the Python "time" module only knows about two timezones: Your local one (with and without daylight savings) and GMT. Therefore, in any other timezones, Pythons time.strftime() cannot correctly render the time. This is particularly apparent in the current DateTime.py, because its strftime method just interprets the internal representation of the time as GMT, whatever. We can fix this easily: *** lib/python/DateTime/DateTime.py Sun Jul 23 20:03:05 2000 --- lib/python/DateTime/DateTime.old.py Sun Jul 23 20:03:04 2000 *************** *** 1376,1382 **** return millis def strftime(self, format): ! return strftime(format, gmtime(self.toZone('GMT').timeTime())) # General formats from previous DateTime def Date(self): --- 1376,1382 ---- return millis def strftime(self, format): ! return strftime(format, gmtime(self.timeTime())) # General formats from previous DateTime def Date(self): Now, at least, the time will be reported correctly, although not really usefully if you want to have the time formatted in the timezone given to the DateTime instance. Also, this patch will cause formatting calls to create a new DateTime instance if the instance you want to format is not in timezone GMT+0. The only general solution that I can see is to replicate the formatting algorithms of the time module in DateTime.py, but written so that they take account of timezones. There is another issue: When I call _.DateTime('2000-07-23'), what do I mean? The current implementation of DateTime interprets that as "midnight (the earliest possible time) on 2000-07-23, interpreted in the local timezone". However, if I'm being naive, I might think that I'm refering to a Day, and that the Day should be the same day no matter what timezone I put it into. In that case, the DateTime module needs rewriting to have a sense of precision built into it: If I specify a time to the day, I get the latter behaviour. If I specify the time more precisely, I get the current behaviour. Another approach would be to make _.DateTime('2000-07-23') mean Midday, GMT rather than Midnight, local time. That would give the latter behaviour for most timezones at most times; the exceptions being places near the international date line that are in daylight savings time. -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
Steve Alexander wrote:
This is particularly apparent in the current DateTime.py, because its strftime method just interprets the internal representation of the time as GMT, whatever.
We can fix this easily:
*** lib/python/DateTime/DateTime.py Sun Jul 23 20:03:05 2000 --- lib/python/DateTime/DateTime.old.py Sun Jul 23 20:03:04 2000 *************** *** 1376,1382 **** return millis
def strftime(self, format): ! return strftime(format, gmtime(self.toZone('GMT').timeTime()))
# General formats from previous DateTime def Date(self): --- 1376,1382 ---- return millis
def strftime(self, format): ! return strftime(format, gmtime(self.timeTime()))
# General formats from previous DateTime def Date(self):
Now, at least, the time will be reported correctly, although not really usefully if you want to have the time formatted in the timezone given to the DateTime instance.
No, no, no! Ignore the patch, it is a placebo :-/ I should read these things back more carefully... The bit about reimplementing time.strftime() in DateTime.py still holds though. -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
Steve Alexander wrote:
No, no, no!
Ignore the patch, it is a placebo :-/ I should read these things back more carefully...
The bit about reimplementing time.strftime() in DateTime.py still holds though.
In brief, though -- and hopefuly clearer this time: If you format DateTimes using strftime (that is, fmt="%d %m" and so forth), you can only have the time rendered in GMT. This is confising the counter-intuitive, as the internal timezone of the DateTime instance is not preserved. The only reasonable way around this is to reimplement the strftime function of Python's time module in DateTime.py, but have it take account of timezones. As another issue, when you create a new DateTime instance with _.DateTime('YYYY-MM-DD'), the actual time stored is midnight in your local timezone. A more useful default time would be midday, GMT. This shouldn't break much code, as the current behaviour isn't well documented and is arguably broken anyway. -- Steve Alexander Software Engineer Cat-Box limited http://www.cat-box.net
participants (1)
-
Steve Alexander