Commits

Jason R. Coombs committed ef34c57

Support ambiguous times

  • Participants
  • Parent commits dbb2d86

Comments (0)

Files changed (3)

File win32/Lib/ambiguous.txt

+Handle Ambiguous Time
+=====================
+
+>>> import datetime
+>>> from win32timezone import *
+>>> ambiguous = datetime.datetime(2011, 11, 6, 1, 15)
+>>> est = TimeZoneInfo('Eastern Standard Time')
+>>> est.dst(ambiguous)
+Traceback (most recent call last):
+[...]
+AmbiguousTimeError: 2011-11-06 01:15:00
+
+>>> datetime.datetime(2011, 11, 6, 6, 0, tzinfo=TimeZoneInfo.utc()).astimezone(est)
+datetime.datetime(2011, 11, 6, 1, 0, tzinfo=TimeZoneInfo('Eastern Standard Time'))

File win32/Lib/consistent-time.txt

+http://docs.python.org/library/datetime.html#datetime.tzinfo.dst says
+tz.utcoffset(dt) - tz.dst(dt) should be consistent for all values of dt.
+
+>>> import sys
+>>> import itertools
+>>> from win32timezone import *
+>>> import datetime
+>>> def test_timezone(tzname):
+...     twenty_min = datetime.timedelta(minutes=20).total_seconds()
+...     times = xrange(0, 1000000, int(twenty_min))
+...     tz = TimeZoneInfo(tzname)
+...     dts = itertools.chain(
+...         (datetime.datetime.utcfromtimestamp(n) for n in times),
+...         (datetime.datetime.fromtimestamp(n).replace(tzinfo=tz) for n in times),
+...     )
+...     answers = set(tz.utcoffset(dt) - tz.dst(dt) for dt in dts)
+...     assert len(answers) == 1
+>>> test_timezone('Pacific Standard Time')

File win32/Lib/win32timezone.py

 datetime.datetime(2011, 11, 5, 19, 0, tzinfo=TimeZoneInfo('Pacific Standard Time'))
 
 Make sure the converted time is correct.
+>>> tz_pac
+TimeZoneInfo('Pacific Standard Time')
 >>> dt_pac = dt_hi.astimezone(tz_pac)
 >>> dt_pac.timetuple()
 time.struct_time(tm_year=2011, tm_mon=11, tm_mday=5, tm_hour=19, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=309, tm_isdst=1)
 		winInfo = self.getWinInfo(dt.year)
 		return winInfo.bias + winInfo.daylight_bias
 
+	def fromutc(self, dt):
+		if dt.tzinfo is not self:
+			raise ValueError("tzinfo is not self")
+		# calculate the local time using the standard offset
+		tz_std = TimeZoneInfo(self.timeZoneName, fix_standard_time=True)
+		delta = tz_std.utcoffset(dt)
+		dt += delta
+		try:
+			dt += self.dst(dt)
+		except AmbiguousTimeError:
+			pass
+		return dt
+
 	def utcoffset(self, dt):
 		"Calculates the utcoffset according to the datetime.tzinfo spec"
 		if dt is None: return
 			#  if there's a standard_bias (which I suspect is always 0).
 			dstStartAdj = dstStart + winInfo.standard_bias
 
+			if dstEndAdj <= dt < dstEnd or dstStartAdj <= dt < dstStart:
+				raise AmbiguousTimeError(dt)
+
 			if dstStart < dstEnd:
 				in_dst = dstStartAdj <= dt < dstEndAdj
 			else:
 GetSortedTimeZoneNames = deprecated(TimeZoneInfo.get_sorted_time_zone_names, 'GetSortedTimeZoneNames')
 # end backward compatibility
 
+class AmbiguousTimeError(Exception):
+	pass
+
 def utcnow():
 	"""
 	Return the UTC time now with timezone awareness as enabled