Package flumotion :: Package common :: Module tz
[hide private]

Source Code for Module flumotion.common.tz

  1  # -*- Mode:Python; test-case-name:flumotion.test.test_common_eventcalendar -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18  import datetime 
 19  import time 
 20   
 21  HAS_DATEUTIL = False 
 22  try: 
 23      from dateutil import tz 
 24      HAS_DATEUTIL = True 
 25  except ImportError: 
 26      pass 
 27   
 28   
29 -def gettz(tzid):
30 """ 31 Gets the right timezone from the environment or the given string 32 """ 33 if not HAS_DATEUTIL: 34 return None 35 return tz.gettz(tzid)
36 37
38 -class DSTTimezone(datetime.tzinfo):
39 """ A tzinfo class representing a DST timezone """ 40 41 ZERO = datetime.timedelta(0) 42
43 - def __init__(self, tzid, stdname, dstname, stdoffset, dstoffset, 44 stdoffsetfrom, dstoffsetfrom, dststart, dstend, 45 stdrrule, dstrrule):
46 ''' 47 @param tzid: Timezone unique ID 48 @type tzid: str 49 @param stdname: Name of the Standard observance 50 @type stdname: str 51 @param dstname: Name of the DST observance 52 @type dstname: str 53 @param stdoffset: UTC offset for the standard observance 54 @type stdoffset: L{datetime.timedelta} 55 @param dstoffset: UTC offset for the DST observance 56 @type dstoffset: L{datetime.timedelta} 57 @param stdoffsetfrom: UTC offset which is in use when the onset of 58 Standard observance begins 59 @type stdoffsetfrom: l{datetime.timedelta} 60 @param dstoffsetfrom: UTC offset which is in use when the onset of 61 DST observance begins 62 @type stdoffsetfrom: L{datetime.timedelta} 63 @param dststart: Start of the DST observance 64 @type dststart: L{datetime.datetime} 65 @param dstend: End of the DST observance 66 @type dstend: L{datetime.datetime} 67 @param stdrrule: Recurrence rule for the standard observance 68 @type stdrrule: L{rrule.rrule} 69 @param dstrrule: Recurrence rule for the daylight observance 70 @type dstrrule: L{rrule.rrule} 71 ''' 72 73 self._tzid = str(tzid) 74 self._stdname = str(stdname) 75 self._dstname = str(dstname) 76 self._stdoffset = stdoffset 77 self._dstoffset = dstoffset 78 self._stdoffsetfrom = stdoffsetfrom 79 self._dstoffsetfrom = dstoffsetfrom 80 self._dststart = dststart 81 self._dstend = dstend 82 self._stdrrule = stdrrule 83 self._dstrrule = dstrrule
84
85 - def __str__(self):
86 return self._tzid
87
88 - def tzname(self, dt):
89 return self._isdst(dt) and self._dstname or self._stdname
90
91 - def utcoffset(self, dt):
92 return self._isdst(dt) and self._dstoffset or self._stdoffset
93
94 - def fromutc(self, dt):
95 dt = dt.replace(tzinfo=None) 96 return self._isdst(dt) and \ 97 dt + self._dstoffsetfrom or dt + self._stdoffsetfrom
98
99 - def dst(self, dt):
100 if dt is None or dt.tzinfo is None: 101 return self.ZERO 102 assert dt.tzinfo is self 103 return self._isdst(dt) and self._dstoffset - self._stdoffset or \ 104 self.ZERO
105
106 - def copy(self):
107 # The substraction is done converting the datetime values to UTC and 108 # adding the utcoffset of each one (see 9.1.4 datetime Objects) 109 # which is done only if both datetime are 'aware' and have different 110 # tzinfo member, that's why we need a way to copy an instance 111 return DSTTimezone(self._tzid, self._stdname, self._dstname, 112 self._stdoffset, self._dstoffset, self._stdoffsetfrom, 113 self._dstoffsetfrom, self._dststart, self._dstend, 114 self._stdrrule, self._dstrrule)
115
116 - def _isdst(self, dt):
117 if self._dstoffset is None or dt.year < self._dststart.year: 118 return False 119 firstDayOfYear = datetime.datetime(dt.year, 1, 1) 120 start = self._dstrrule.after(firstDayOfYear, True) 121 end = self._stdrrule.after(firstDayOfYear) 122 return start <= dt.replace(tzinfo=None) < end
123 124
125 -class FixedOffsetTimezone(datetime.tzinfo):
126 """Fixed offset in hours from UTC.""" 127
128 - def __init__(self, offset, name):
129 self.__offset = offset 130 self.__name = name
131
132 - def utcoffset(self, dt):
133 return self.__offset
134
135 - def tzname(self, dt):
136 return self.__name
137
138 - def dst(self, dt):
139 return datetime.timedelta(0)
140
141 - def copy(self):
142 return FixedOffsetTimezone(self.__offset, self.__name)
143 144
145 -class LocalTimezone(datetime.tzinfo):
146 """A tzinfo class representing the system's idea of the local timezone""" 147 148 EPOCHORDINAL = datetime.datetime.utcfromtimestamp(0).toordinal() 149 ZERO = datetime.timedelta(0) 150
151 - def __init__(self):
152 datetime.tzinfo.__init__(self) 153 self._std_offset = datetime.timedelta(seconds=-time.timezone) 154 if time.daylight: 155 self._dst_offset = datetime.timedelta(seconds=-time.altzone) 156 else: 157 self._dst_offset = self._std_offset 158 self._dst_diff = self._dst_offset - self._std_offset
159
160 - def utcoffset(self, dt):
161 if self._isdst(dt): 162 return self._dst_offset 163 else: 164 return self._std_offset
165
166 - def dst(self, dt):
167 if self._isdst(dt): 168 return self._dst_diff 169 else: 170 return self.ZERO
171
172 - def tzname(self, dt):
173 return time.tzname[self._isdst(dt)]
174
175 - def _isdst(self, dt):
176 timestamp = ((dt.toordinal() - self.EPOCHORDINAL) * 86400 177 + dt.hour * 3600 178 + dt.minute * 60 179 + dt.second) 180 return time.localtime(timestamp+time.timezone).tm_isdst
181 LOCAL = LocalTimezone() 182 183
184 -class UTCTimezone(datetime.tzinfo):
185 """A tzinfo class representing UTC""" 186 ZERO = datetime.timedelta(0) 187
188 - def utcoffset(self, dt):
189 return self.ZERO
190
191 - def tzname(self, dt):
192 return "UTC"
193
194 - def dst(self, dt):
195 return self.ZERO
196 UTC = UTCTimezone() 197