[pywin32-checkins] pywin32/win32/Lib win32timezone.py,1.17,1.18
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
|
From: Jason R. C. <ja...@us...> - 2009-01-14 04:06:19
|
Update of /cvsroot/pywin32/pywin32/win32/Lib In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv7086 Modified Files: win32timezone.py Log Message: Added a local implementation of GetTimeZoneInformation using ctypes in order to get a raw SYSTEMTIME object. Used the raw TIME_ZONE_INFORMATION and SYSTEMTIME structures to initialize a TimeZoneInformation purely from a TIME_ZONE_INFORMATION. All tests pass except for the pickle test. Index: win32timezone.py =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/Lib/win32timezone.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** win32timezone.py 14 Jan 2009 03:01:13 -0000 1.17 --- win32timezone.py 14 Jan 2009 04:06:02 -0000 1.18 *************** *** 13,17 **** Written by Jason R. Coombs (ja...@ja...). ! Copyright © 2003-2008. All Rights Reserved. --- 13,17 ---- Written by Jason R. Coombs (ja...@ja...). ! Copyright © 2003-2009. All Rights Reserved. *************** *** 133,136 **** --- 133,137 ---- import datetime import win32api + import ctypes import re import sys *************** *** 148,182 **** def __init__(self, param): isinstance(param, basestring) and self.__load_bytes(param) ! isinstance(param, tuple) and self.__load_tuple(param) def __load_bytes(self, bytes): components = struct.unpack(self.format, bytes) ! bias, std_bias, dlt_bias = components[:3] ! daylight_times = components[3:11], components[11:19] ! std_start, dlt_start = map(pywintypes.Time, daylight_times) ! std_name = dlt_name = None ! tz_tuple = (bias, std_name, std_start, std_bias, dlt_name, dlt_start, dlt_bias) ! self.__load_values(tz_tuple) ! tuple_fields = ('bias', 'std_name', 'std_start', 'std_bias', 'dlt_name', 'dlt_start', 'dlt_bias') ! ! def __load_values(self, tz_tuple): ! "tz_tuple is a tuple such as the one returned from win32api.GetTimeZoneInformation" ! tz_dict = dict(zip(self.tuple_fields, tz_tuple)) make_minute_time_delta = lambda m: datetime.timedelta(minutes = m) ! bias_vars = [var for var in tz_dict.keys() if 'bias' in var] ! for name in bias_vars: ! bias = make_minute_time_delta(tz_dict[name]) ! setattr(self, name, bias) ! time_vars = [var for var in tz_dict.keys() if 'start' in var] ! for name in time_vars: ! value = pywintypes.Time(tz_dict[name]) setattr(self, name, value) def LocateStartDay(self, year): ! return self._locate_day(year, self.dlt_start) def LocateEndDay(self, year): ! return self._locate_day(year, self.std_start) @staticmethod --- 149,182 ---- def __init__(self, param): isinstance(param, basestring) and self.__load_bytes(param) ! isinstance(param, TIME_ZONE_INFORMATION) and self.__load_time_zone_information(param) def __load_bytes(self, bytes): components = struct.unpack(self.format, bytes) ! bias, standard_bias, daylight_bias = components[:3] ! standard_start = SYSTEMTIME(*components[3:11]) ! daylight_start = SYSTEMTIME(*components[11:19]) ! standard_name = daylight_name = "" ! tzi = TIME_ZONE_INFORMATION(bias, ! standard_name, standard_start, standard_bias, ! daylight_name, daylight_start, daylight_bias,) ! self.__load_time_zone_information(tzi) ! def __load_time_zone_information(self, tzi): ! """Copy all the attributes from a TIME_ZONE_INFORMATION structure, ! converting bias values to timedelta objects along the way.""" ! # TODO: consider merging this class with TIME_ZONE_INFORMATION make_minute_time_delta = lambda m: datetime.timedelta(minutes = m) ! bias_fields = [field for field in tzi.fields() if 'bias' in field] ! for name in tzi.fields(): ! value = getattr(tzi, name) ! if 'bias' in name: ! value = make_minute_time_delta(value) setattr(self, name, value) def LocateStartDay(self, year): ! return self._locate_day(year, self.daylight_start) def LocateEndDay(self, year): ! return self._locate_day(year, self.standard_start) @staticmethod *************** *** 192,200 **** >>> SATURDAY = 6 >>> MARCH = 3 ! >>> SYSTEMTIME_tuple = (2000, MARCH, SATURDAY, 4, 0, 0, 0, 0) # according to my calendar, the 4th Saturday in March in 2009 was the 28th >>> expected_date = datetime.datetime(2009, 3, 28) ! >>> WinTZI._locate_day(2009, pywintypes.Time(SYSTEMTIME_tuple)) == expected_date True --- 192,200 ---- >>> SATURDAY = 6 >>> MARCH = 3 ! >>> st = SYSTEMTIME(2000, MARCH, SATURDAY, 4, 0, 0, 0, 0) # according to my calendar, the 4th Saturday in March in 2009 was the 28th >>> expected_date = datetime.datetime(2009, 3, 28) ! >>> WinTZI._locate_day(2009, st) == expected_date True *************** *** 204,208 **** """ # MS stores Sunday as 0, Python datetime stores Monday as zero ! target_weekday = (cutoff.weekday + 6) % 7 # For SYSTEMTIMEs relating to time zone inforamtion, cutoff.day # is the week of the month --- 204,208 ---- """ # MS stores Sunday as 0, Python datetime stores Monday as zero ! target_weekday = (cutoff.day_of_week + 6) % 7 # For SYSTEMTIMEs relating to time zone inforamtion, cutoff.day # is the week of the month *************** *** 211,217 **** day = (week_of_month - 1) * 7 + 1 result = datetime.datetime(year, cutoff.month, day, ! cutoff.hour, cutoff.minute, cutoff.second, cutoff.msec) # now the result is the correct week, but not necessarily the correct day of the week ! days_to_go = target_weekday - result.weekday() result += datetime.timedelta(days_to_go) # if we selected a day in the month following the target month, --- 211,217 ---- day = (week_of_month - 1) * 7 + 1 result = datetime.datetime(year, cutoff.month, day, ! cutoff.hour, cutoff.minute, cutoff.second, cutoff.millisecond) # now the result is the correct week, but not necessarily the correct day of the week ! days_to_go = (target_weekday - result.weekday()) % 7 result += datetime.timedelta(days_to_go) # if we selected a day in the month following the target month, *************** *** 220,224 **** # to be the last week in a month and adding the time delta might have # pushed the result into the next month. ! while result.month == month + 1: result -= datetime.timedelta(weeks = 1) return result --- 220,224 ---- # to be the last week in a month and adding the time delta might have # pushed the result into the next month. ! while result.month == cutoff.month + 1: result -= datetime.timedelta(weeks = 1) return result *************** *** 276,283 **** def _LoadFromTZI(self, tzi): ! self.timeZoneName = tzi.std_name self.displayName = 'Unknown' ! self.standardName = tzi.std_name ! self.daylightName = tzi.dlt_name self.staticInfo = tzi --- 276,283 ---- def _LoadFromTZI(self, tzi): ! self.timeZoneName = tzi.standard_name self.displayName = 'Unknown' ! self.standardName = tzi.standard_name ! self.daylightName = tzi.daylight_name self.staticInfo = tzi *************** *** 307,313 **** def tzname(self, dt): winInfo = self.getWinInfo(dt) ! if self.dst(dt) == winInfo.dlt_bias: result = self.daylightName ! elif self.dst(dt) == winInfo.std_bias: result = self.standardName return result --- 307,313 ---- def tzname(self, dt): winInfo = self.getWinInfo(dt) ! if self.dst(dt) == winInfo.daylight_bias: result = self.daylightName ! elif self.dst(dt) == winInfo.standard_bias: result = self.standardName return result *************** *** 323,331 **** def _getStandardBias(self, dt): winInfo = self.getWinInfo(dt.year) ! return winInfo.bias + winInfo.std_bias def _getDaylightBias(self, dt): winInfo = self.getWinInfo(dt.year) ! return winInfo.bias + winInfo.dlt_bias def utcoffset(self, dt): --- 323,331 ---- def _getStandardBias(self, dt): winInfo = self.getWinInfo(dt.year) ! return winInfo.bias + winInfo.standard_bias def _getDaylightBias(self, dt): winInfo = self.getWinInfo(dt.year) ! return winInfo.bias + winInfo.daylight_bias def utcoffset(self, dt): *************** *** 342,348 **** winInfo = self.getWinInfo(dt.year) if not self.fixedStandardTime and self._inDaylightSavings(dt): ! result = winInfo.dlt_bias else: ! result = winInfo.std_bias return result --- 342,348 ---- winInfo = self.getWinInfo(dt.year) if not self.fixedStandardTime and self._inDaylightSavings(dt): ! result = winInfo.daylight_bias else: ! result = winInfo.standard_bias return result *************** *** 524,530 **** si = other.staticInfo same_bias = si.bias==self.ZERO ! same_standard_bias = si.std_bias==self.ZERO no_dst = other.fixedStandardTime == True ! same_daylight_bias = no_dst or si.dlt_bias==self.ZERO return same_bias and same_standard_bias and same_daylight_bias --- 524,530 ---- si = other.staticInfo same_bias = si.bias==self.ZERO ! same_standard_bias = si.standard_bias==self.ZERO no_dst = other.fixedStandardTime == True ! same_daylight_bias = no_dst or si.daylight_bias==self.ZERO return same_bias and same_standard_bias and same_daylight_bias *************** *** 567,571 **** True """ ! code, result = win32api.GetTimeZoneInformation() info = WinTZI(result) # code is 0 if daylight savings is disabled or not defined --- 567,571 ---- True """ ! code, result = GetTimeZoneInformation() info = WinTZI(result) # code is 0 if daylight savings is disabled or not defined *************** *** 703,704 **** --- 703,736 ---- def __new__(cls): return RangeItem.__new__(cls, -1) + + # some win32api stuff to get raw SYSTEMTIME structures + class SYSTEMTIME(ctypes.Structure): + _fields_ = [ + ('year', ctypes.c_ushort), + ('month', ctypes.c_ushort), + ('day_of_week', ctypes.c_ushort), + ('day', ctypes.c_ushort), + ('hour', ctypes.c_ushort), + ('minute', ctypes.c_ushort), + ('second', ctypes.c_ushort), + ('millisecond', ctypes.c_ushort), + ] + + class TIME_ZONE_INFORMATION(ctypes.Structure): + _fields_ = [ + ('bias', ctypes.c_long), + ('standard_name', ctypes.c_wchar*32), + ('standard_start', SYSTEMTIME), + ('standard_bias', ctypes.c_long), + ('daylight_name', ctypes.c_wchar*32), + ('daylight_start', SYSTEMTIME), + ('daylight_bias', ctypes.c_long), + ] + + def fields(self): + return map(operator.itemgetter(0), self._fields_) + + def GetTimeZoneInformation(): + tzi = TIME_ZONE_INFORMATION() + code = ctypes.windll.kernel32.GetTimeZoneInformation(ctypes.byref(tzi)) + return code, tzi |