[Zope3-checkins] SVN: Zope3/trunk/src/zope/i18n/ Fix i18n datetime
construction and improve tests
Stuart Bishop
stuart at stuartbishop.net
Wed Sep 7 00:46:17 EDT 2005
Log message for revision 38336:
Fix i18n datetime construction and improve tests
Changed:
U Zope3/trunk/src/zope/i18n/format.py
U Zope3/trunk/src/zope/i18n/tests/test_formats.py
-=-
Modified: Zope3/trunk/src/zope/i18n/format.py
===================================================================
--- Zope3/trunk/src/zope/i18n/format.py 2005-09-07 04:29:43 UTC (rev 38335)
+++ Zope3/trunk/src/zope/i18n/format.py 2005-09-07 04:46:17 UTC (rev 38336)
@@ -130,6 +130,7 @@
# Handle timezones
tzinfo = None
+ pytz_tzinfo = False # If True, we should use pytz specific syntax
tz_entry = _findFormattingCharacterInPattern('z', bin_pattern)
if ordered[3:] != [None, None, None, None] and tz_entry:
length = tz_entry[0][1]
@@ -137,32 +138,54 @@
if length == 1:
hours, mins = int(value[:-2]), int(value[-2:])
delta = datetime.timedelta(hours=hours, minutes=mins)
+ # XXX: I think this is making an unpickable tzinfo.
+ # Note that StaticTzInfo is not part of the exposed pytz API.
tzinfo = pytz.tzinfo.StaticTzInfo()
tzinfo._utcoffset = delta
+ pytz_tzinfo = True
elif length == 2:
hours, mins = int(value[:-3]), int(value[-2:])
delta = datetime.timedelta(hours=hours, minutes=mins)
+ # XXX: I think this is making an unpickable tzinfo.
+ # Note that StaticTzInfo is not part of the exposed pytz API.
tzinfo = pytz.tzinfo.StaticTzInfo()
tzinfo._utcoffset = delta
+ pytz_tzinfo = True
else:
- if value in pytz.all_timezones:
+ try:
tzinfo = pytz.timezone(value)
- else:
+ pytz_tzinfo = True
+ except KeyError:
# TODO: Find timezones using locale information
pass
-
# Create a date/time object from the data
+ # If we have a pytz tzinfo, we need to invoke localize() as per
+ # the pytz documentation on creating local times.
+ # NB. If we are in an end-of-DST transition period, we have a 50%
+ # chance of getting a time 1 hour out here, but that is the price
+ # paid for dealing with localtimes.
if ordered[3:] == [None, None, None, None]:
return datetime.date(*[e or 0 for e in ordered[:3]])
elif ordered[:3] == [None, None, None]:
- return datetime.time(*[e or 0 for e in ordered[3:]],
- **{'tzinfo' :tzinfo})
+ if pytz_tzinfo:
+ return tzinfo.localize(
+ datetime.time(*[e or 0 for e in ordered[3:]])
+ )
+ else:
+ return datetime.time(
+ *[e or 0 for e in ordered[3:]], **{'tzinfo' :tzinfo}
+ )
else:
- return datetime.datetime(*[e or 0 for e in ordered],
- **{'tzinfo' :tzinfo})
+ if pytz_tzinfo:
+ return tzinfo.localize(datetime.datetime(
+ *[e or 0 for e in ordered]
+ ))
+ else:
+ return datetime.datetime(
+ *[e or 0 for e in ordered], **{'tzinfo' :tzinfo}
+ )
-
def format(self, obj, pattern=None):
"See zope.i18n.interfaces.IFormat"
# Make or get binary form of datetime pattern
@@ -599,7 +622,7 @@
week_in_month = (dt.day + 6 - dt.weekday()) / 7 + 1
# Getting the timezone right
- tzinfo = dt.tzinfo or pytz.reference.utc
+ tzinfo = dt.tzinfo or pytz.utc
tz_secs = tzinfo.utcoffset(dt).seconds
tz_secs = (tz_secs > 12*3600) and tz_secs-24*3600 or tz_secs
tz_mins = int(math.fabs(tz_secs % 3600 / 60))
Modified: Zope3/trunk/src/zope/i18n/tests/test_formats.py
===================================================================
--- Zope3/trunk/src/zope/i18n/tests/test_formats.py 2005-09-07 04:29:43 UTC (rev 38335)
+++ Zope3/trunk/src/zope/i18n/tests/test_formats.py 2005-09-07 04:46:17 UTC (rev 38336)
@@ -302,19 +302,41 @@
self.assertEqual(dt.tzinfo.tzname(dt), None)
def testParseTimeZoneNames(self):
+ # Note that EST is a deprecated timezone name since it is a US
+ # interpretation (other countries also use the EST timezone
+ # abbreviation)
dt = self.format.parse('01.01.2003 09:48 EST', 'dd.MM.yyyy HH:mm zzz')
- self.assertEqual(dt.tzinfo.utcoffset(dt), datetime.timedelta(hours=-6))
+ self.assertEqual(dt.tzinfo.utcoffset(dt), datetime.timedelta(hours=-5))
self.assertEqual(dt.tzinfo.zone, 'EST')
- # I think this is wrong due to a bug in pytz
- self.assertEqual(dt.tzinfo.tzname(dt), 'CST')
+ self.assertEqual(dt.tzinfo.tzname(dt), 'EST')
dt = self.format.parse('01.01.2003 09:48 US/Eastern',
'dd.MM.yyyy HH:mm zzzz')
self.assertEqual(dt.tzinfo.utcoffset(dt), datetime.timedelta(hours=-5))
self.assertEqual(dt.tzinfo.zone, 'US/Eastern')
- # I think this is wrong due to a bug in pytz
self.assertEqual(dt.tzinfo.tzname(dt), 'EST')
+ dt = self.format.parse('01.01.2003 09:48 Australia/Sydney',
+ 'dd.MM.yyyy HH:mm zzzz')
+ self.assertEqual(dt.tzinfo.utcoffset(dt), datetime.timedelta(hours=11))
+ self.assertEqual(dt.tzinfo.zone, 'Australia/Sydney')
+ self.assertEqual(dt.tzinfo.tzname(dt), 'EST')
+
+ # Note that historical and future (as far as known)
+ # timezones are handled happily using the pytz timezone database
+ # US DST transition points are changing in 2007
+ dt = self.format.parse('01.04.2006 09:48 US/Eastern',
+ 'dd.MM.yyyy HH:mm zzzz')
+ self.assertEqual(dt.tzinfo.zone, 'US/Eastern')
+ self.assertEqual(dt.tzinfo.tzname(dt), 'EST')
+ self.assertEqual(dt.tzinfo.utcoffset(dt), datetime.timedelta(hours=-5))
+ dt = self.format.parse('01.04.2007 09:48 US/Eastern',
+ 'dd.MM.yyyy HH:mm zzzz')
+ self.assertEqual(dt.tzinfo.zone, 'US/Eastern')
+ self.assertEqual(dt.tzinfo.tzname(dt), 'EDT')
+ self.assertEqual(dt.tzinfo.utcoffset(dt), datetime.timedelta(hours=-4))
+
+
def testDateTimeParseError(self):
self.assertRaises(DateTimeParseError,
self.format.parse, '02.01.03 21:48', 'dd.MM.yyyy HH:mm')
More information about the Zope3-Checkins
mailing list