jpayne@69
|
1 Pytz Support
|
jpayne@69
|
2 ============
|
jpayne@69
|
3
|
jpayne@69
|
4 Allows the pytz package to be used for time zone information. The
|
jpayne@69
|
5 advantage of using pytz is that it has a more complete and up to date
|
jpayne@69
|
6 time zone and daylight savings time database.
|
jpayne@69
|
7
|
jpayne@69
|
8 Usage
|
jpayne@69
|
9 -----
|
jpayne@69
|
10 You don't have to do anything special to make it work.
|
jpayne@69
|
11
|
jpayne@69
|
12 >>> from DateTime import DateTime, Timezones
|
jpayne@69
|
13 >>> d = DateTime('March 11, 2007 US/Eastern')
|
jpayne@69
|
14
|
jpayne@69
|
15 Daylight Savings
|
jpayne@69
|
16 ----------------
|
jpayne@69
|
17 In 2007 daylight savings time in the US was changed. The Energy Policy
|
jpayne@69
|
18 Act of 2005 mandates that DST will start on the second Sunday in March
|
jpayne@69
|
19 and end on the first Sunday in November.
|
jpayne@69
|
20
|
jpayne@69
|
21 In 2007, the start and stop dates are March 11 and November 4,
|
jpayne@69
|
22 respectively. These dates are different from previous DST start and
|
jpayne@69
|
23 stop dates. In 2006, the dates were the first Sunday in April (April
|
jpayne@69
|
24 2, 2006) and the last Sunday in October (October 29, 2006).
|
jpayne@69
|
25
|
jpayne@69
|
26 Let's make sure that DateTime can deal with this, since the primary
|
jpayne@69
|
27 motivation to use pytz for time zone information is the fact that it
|
jpayne@69
|
28 is kept up to date with daylight savings changes.
|
jpayne@69
|
29
|
jpayne@69
|
30 >>> DateTime('March 11, 2007 US/Eastern').tzoffset()
|
jpayne@69
|
31 -18000
|
jpayne@69
|
32 >>> DateTime('March 12, 2007 US/Eastern').tzoffset()
|
jpayne@69
|
33 -14400
|
jpayne@69
|
34 >>> DateTime('November 4, 2007 US/Eastern').tzoffset()
|
jpayne@69
|
35 -14400
|
jpayne@69
|
36 >>> DateTime('November 5, 2007 US/Eastern').tzoffset()
|
jpayne@69
|
37 -18000
|
jpayne@69
|
38
|
jpayne@69
|
39 Let's compare this to 2006.
|
jpayne@69
|
40
|
jpayne@69
|
41 >>> DateTime('April 2, 2006 US/Eastern').tzoffset()
|
jpayne@69
|
42 -18000
|
jpayne@69
|
43 >>> DateTime('April 3, 2006 US/Eastern').tzoffset()
|
jpayne@69
|
44 -14400
|
jpayne@69
|
45 >>> DateTime('October 29, 2006 US/Eastern').tzoffset()
|
jpayne@69
|
46 -14400
|
jpayne@69
|
47 >>> DateTime('October 30, 2006 US/Eastern').tzoffset()
|
jpayne@69
|
48 -18000
|
jpayne@69
|
49
|
jpayne@69
|
50 Time Zones
|
jpayne@69
|
51 ---------
|
jpayne@69
|
52 DateTime can use pytz's large database of time zones. Here are some
|
jpayne@69
|
53 examples:
|
jpayne@69
|
54
|
jpayne@69
|
55 >>> d = DateTime('Pacific/Kwajalein')
|
jpayne@69
|
56 >>> d = DateTime('America/Shiprock')
|
jpayne@69
|
57 >>> d = DateTime('Africa/Ouagadougou')
|
jpayne@69
|
58
|
jpayne@69
|
59 Of course pytz doesn't know about everything.
|
jpayne@69
|
60
|
jpayne@69
|
61 >>> from DateTime.interfaces import SyntaxError
|
jpayne@69
|
62 >>> try:
|
jpayne@69
|
63 ... d = DateTime('July 21, 1969 Moon/Eastern')
|
jpayne@69
|
64 ... print('fail')
|
jpayne@69
|
65 ... except SyntaxError:
|
jpayne@69
|
66 ... print('ok')
|
jpayne@69
|
67 ok
|
jpayne@69
|
68
|
jpayne@69
|
69 You can still use zone names that DateTime defines that aren't part of
|
jpayne@69
|
70 the pytz database.
|
jpayne@69
|
71
|
jpayne@69
|
72 >>> d = DateTime('eet')
|
jpayne@69
|
73 >>> d = DateTime('iceland')
|
jpayne@69
|
74
|
jpayne@69
|
75 These time zones use DateTimes database. So it's preferable to use the
|
jpayne@69
|
76 official time zone name.
|
jpayne@69
|
77
|
jpayne@69
|
78 One trickiness is that DateTime supports some zone name
|
jpayne@69
|
79 abbreviations. Some of these map to pytz names, so these abbreviations
|
jpayne@69
|
80 will give you time zone date from pytz. Notable among abbreviations
|
jpayne@69
|
81 that work this way are 'est', 'cst', 'mst', and 'pst'.
|
jpayne@69
|
82
|
jpayne@69
|
83 Let's verify that 'est' picks up the 2007 daylight savings time changes.
|
jpayne@69
|
84
|
jpayne@69
|
85 >>> DateTime('March 11, 2007 est').tzoffset()
|
jpayne@69
|
86 -18000
|
jpayne@69
|
87 >>> DateTime('March 12, 2007 est').tzoffset()
|
jpayne@69
|
88 -14400
|
jpayne@69
|
89 >>> DateTime('November 4, 2007 est').tzoffset()
|
jpayne@69
|
90 -14400
|
jpayne@69
|
91 >>> DateTime('November 5, 2007 est').tzoffset()
|
jpayne@69
|
92 -18000
|
jpayne@69
|
93
|
jpayne@69
|
94 You can get a list of time zones supported by calling the Timezones() function.
|
jpayne@69
|
95
|
jpayne@69
|
96 >>> Timezones() #doctest: +ELLIPSIS
|
jpayne@69
|
97 ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', ...]
|
jpayne@69
|
98
|
jpayne@69
|
99 Note that you can mess with this list without hurting things.
|
jpayne@69
|
100
|
jpayne@69
|
101 >>> t = Timezones()
|
jpayne@69
|
102 >>> t.remove('US/Eastern')
|
jpayne@69
|
103 >>> d = DateTime('US/Eastern')
|
jpayne@69
|
104
|
jpayne@69
|
105
|
jpayne@69
|
106 Internal Components
|
jpayne@69
|
107 -------------------
|
jpayne@69
|
108
|
jpayne@69
|
109 The following are tests of internal components.
|
jpayne@69
|
110
|
jpayne@69
|
111 Cache
|
jpayne@69
|
112 ~~~~~
|
jpayne@69
|
113
|
jpayne@69
|
114 The DateTime class uses a new time zone cache.
|
jpayne@69
|
115
|
jpayne@69
|
116 >>> from DateTime.DateTime import _TZINFO
|
jpayne@69
|
117 >>> _TZINFO #doctest: +ELLIPSIS
|
jpayne@69
|
118 <DateTime.pytz_support.PytzCache ...>
|
jpayne@69
|
119
|
jpayne@69
|
120 The cache maps time zone names to time zone instances.
|
jpayne@69
|
121
|
jpayne@69
|
122 >>> cache = _TZINFO
|
jpayne@69
|
123 >>> tz = cache['GMT+730']
|
jpayne@69
|
124 >>> tz = cache['US/Mountain']
|
jpayne@69
|
125
|
jpayne@69
|
126 The cache also must provide a few attributes for use by the DateTime
|
jpayne@69
|
127 class.
|
jpayne@69
|
128
|
jpayne@69
|
129 The _zlst attribute is a list of supported time zone names.
|
jpayne@69
|
130
|
jpayne@69
|
131 >>> cache._zlst #doctest: +ELLIPSIS
|
jpayne@69
|
132 ['Africa/Abidjan'... 'Africa/Accra'... 'IDLE'... 'NZST'... 'NZT'...]
|
jpayne@69
|
133
|
jpayne@69
|
134 The _zidx attribute is a list of lower-case and possibly abbreviated
|
jpayne@69
|
135 time zone names that can be mapped to official zone names.
|
jpayne@69
|
136
|
jpayne@69
|
137 >>> 'australia/yancowinna' in cache._zidx
|
jpayne@69
|
138 True
|
jpayne@69
|
139 >>> 'europe/isle_of_man' in cache._zidx
|
jpayne@69
|
140 True
|
jpayne@69
|
141 >>> 'gmt+0500' in cache._zidx
|
jpayne@69
|
142 True
|
jpayne@69
|
143
|
jpayne@69
|
144 Note that there are more items in _zidx than in _zlst since there are
|
jpayne@69
|
145 multiple names for some time zones.
|
jpayne@69
|
146
|
jpayne@69
|
147 >>> len(cache._zidx) > len(cache._zlst)
|
jpayne@69
|
148 True
|
jpayne@69
|
149
|
jpayne@69
|
150 Each entry in _zlst should also be present in _zidx in lower case form.
|
jpayne@69
|
151
|
jpayne@69
|
152 >>> for name in cache._zlst:
|
jpayne@69
|
153 ... if not name.lower() in cache._zidx:
|
jpayne@69
|
154 ... print("Error %s not in _zidx" % name.lower())
|
jpayne@69
|
155
|
jpayne@69
|
156 The _zmap attribute maps the names in _zidx to official names in _zlst.
|
jpayne@69
|
157
|
jpayne@69
|
158 >>> cache._zmap['africa/abidjan']
|
jpayne@69
|
159 'Africa/Abidjan'
|
jpayne@69
|
160 >>> cache._zmap['gmt+1']
|
jpayne@69
|
161 'GMT+1'
|
jpayne@69
|
162 >>> cache._zmap['gmt+0100']
|
jpayne@69
|
163 'GMT+1'
|
jpayne@69
|
164 >>> cache._zmap['utc']
|
jpayne@69
|
165 'UTC'
|
jpayne@69
|
166
|
jpayne@69
|
167 Let's make sure that _zmap and _zidx agree.
|
jpayne@69
|
168
|
jpayne@69
|
169 >>> idx = set(cache._zidx)
|
jpayne@69
|
170 >>> keys = set(cache._zmap.keys())
|
jpayne@69
|
171 >>> idx == keys
|
jpayne@69
|
172 True
|
jpayne@69
|
173
|
jpayne@69
|
174 Timezone objects
|
jpayne@69
|
175 ~~~~~~~~~~~~~~~~
|
jpayne@69
|
176 The timezone instances have only one public method info(). It returns
|
jpayne@69
|
177 a tuple of (offset, is_dst, name). The method takes a timestamp, which
|
jpayne@69
|
178 is used to determine dst information.
|
jpayne@69
|
179
|
jpayne@69
|
180 >>> t1 = DateTime('November 4, 00:00 2007 US/Mountain').timeTime()
|
jpayne@69
|
181 >>> t2 = DateTime('November 4, 02:00 2007 US/Mountain').timeTime()
|
jpayne@69
|
182 >>> tz.info(t1)
|
jpayne@69
|
183 (-21600, 1, 'MDT')
|
jpayne@69
|
184 >>> tz.info(t2)
|
jpayne@69
|
185 (-25200, 0, 'MST')
|
jpayne@69
|
186
|
jpayne@69
|
187 If you don't pass any arguments to info it provides daylight savings
|
jpayne@69
|
188 time information as of today.
|
jpayne@69
|
189
|
jpayne@69
|
190 >>> tz.info() in ((-21600, 1, 'MDT'), (-25200, 0, 'MST'))
|
jpayne@69
|
191 True
|
jpayne@69
|
192
|