| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
| 2 | <html> |
| 3 | <head> |
| 4 | <link rel="STYLESHEET" href="lib.css" type='text/css' /> |
| 5 | <link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" /> |
| 6 | <link rel='start' href='../index.html' title='Python Documentation Index' /> |
| 7 | <link rel="first" href="lib.html" title='Python Library Reference' /> |
| 8 | <link rel='contents' href='contents.html' title="Contents" /> |
| 9 | <link rel='index' href='genindex.html' title='Index' /> |
| 10 | <link rel='last' href='about.html' title='About this document...' /> |
| 11 | <link rel='help' href='about.html' title='About this document...' /> |
| 12 | <link rel="next" href="node257.html" /> |
| 13 | <link rel="prev" href="datetime-time.html" /> |
| 14 | <link rel="parent" href="module-datetime.html" /> |
| 15 | <link rel="next" href="node257.html" /> |
| 16 | <meta name='aesop' content='information' /> |
| 17 | <title>6.10.6 tzinfo Objects </title> |
| 18 | </head> |
| 19 | <body> |
| 20 | <DIV CLASS="navigation"> |
| 21 | <div id='top-navigation-panel' xml:id='top-navigation-panel'> |
| 22 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 23 | <tr> |
| 24 | <td class='online-navigation'><a rel="prev" title="6.10.5 time Objects" |
| 25 | href="datetime-time.html"><img src='../icons/previous.png' |
| 26 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 27 | <td class='online-navigation'><a rel="parent" title="6.10 datetime " |
| 28 | href="module-datetime.html"><img src='../icons/up.png' |
| 29 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 30 | <td class='online-navigation'><a rel="next" title="6.10.7 strftime() Behavior" |
| 31 | href="node257.html"><img src='../icons/next.png' |
| 32 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 33 | <td align="center" width="100%">Python Library Reference</td> |
| 34 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 35 | href="contents.html"><img src='../icons/contents.png' |
| 36 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 37 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' |
| 38 | border='0' height='32' alt='Module Index' width='32' /></a></td> |
| 39 | <td class='online-navigation'><a rel="index" title="Index" |
| 40 | href="genindex.html"><img src='../icons/index.png' |
| 41 | border='0' height='32' alt='Index' width='32' /></A></td> |
| 42 | </tr></table> |
| 43 | <div class='online-navigation'> |
| 44 | <b class="navlabel">Previous:</b> |
| 45 | <a class="sectref" rel="prev" href="datetime-time.html">6.10.5 time Objects</A> |
| 46 | <b class="navlabel">Up:</b> |
| 47 | <a class="sectref" rel="parent" href="module-datetime.html">6.10 datetime </A> |
| 48 | <b class="navlabel">Next:</b> |
| 49 | <a class="sectref" rel="next" href="node257.html">6.10.7 strftime() Behavior</A> |
| 50 | </div> |
| 51 | <hr /></div> |
| 52 | </DIV> |
| 53 | <!--End of Navigation Panel--> |
| 54 | |
| 55 | <H2><A NAME="SECTION0081060000000000000000"></A><A NAME="datetime-tzinfo"></A> |
| 56 | <BR> |
| 57 | 6.10.6 <tt class="class">tzinfo</tt> Objects |
| 58 | </H2> |
| 59 | |
| 60 | <P> |
| 61 | <tt class="class">tzinfo</tt> is an abstract base clase, meaning that this class |
| 62 | should not be instantiated directly. You need to derive a concrete |
| 63 | subclass, and (at least) supply implementations of the standard |
| 64 | <tt class="class">tzinfo</tt> methods needed by the <tt class="class">datetime</tt> methods you |
| 65 | use. The <tt class="module">datetime</tt> module does not supply any concrete |
| 66 | subclasses of <tt class="class">tzinfo</tt>. |
| 67 | |
| 68 | <P> |
| 69 | An instance of (a concrete subclass of) <tt class="class">tzinfo</tt> can be passed |
| 70 | to the constructors for <tt class="class">datetime</tt> and <tt class="class">time</tt> objects. |
| 71 | The latter objects view their members as being in local time, and the |
| 72 | <tt class="class">tzinfo</tt> object supports methods revealing offset of local time |
| 73 | from UTC, the name of the time zone, and DST offset, all relative to a |
| 74 | date or time object passed to them. |
| 75 | |
| 76 | <P> |
| 77 | Special requirement for pickling: A <tt class="class">tzinfo</tt> subclass must have an |
| 78 | <tt class="method">__init__</tt> method that can be called with no arguments, else it |
| 79 | can be pickled but possibly not unpickled again. This is a technical |
| 80 | requirement that may be relaxed in the future. |
| 81 | |
| 82 | <P> |
| 83 | A concrete subclass of <tt class="class">tzinfo</tt> may need to implement the |
| 84 | following methods. Exactly which methods are needed depends on the |
| 85 | uses made of aware <tt class="module">datetime</tt> objects. If in doubt, simply |
| 86 | implement all of them. |
| 87 | |
| 88 | <P> |
| 89 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 90 | <td><nobr><b><tt id='l2h-1940' xml:id='l2h-1940' class="method">utcoffset</tt></b>(</nobr></td> |
| 91 | <td><var>self, dt</var>)</td></tr></table></dt> |
| 92 | <dd> |
| 93 | Return offset of local time from UTC, in minutes east of UTC. If |
| 94 | local time is west of UTC, this should be negative. Note that this |
| 95 | is intended to be the total offset from UTC; for example, if a |
| 96 | <tt class="class">tzinfo</tt> object represents both time zone and DST adjustments, |
| 97 | <tt class="method">utcoffset()</tt> should return their sum. If the UTC offset |
| 98 | isn't known, return <code>None</code>. Else the value returned must be |
| 99 | a <tt class="class">timedelta</tt> object specifying a whole number of minutes in the |
| 100 | range -1439 to 1439 inclusive (1440 = 24*60; the magnitude of the offset |
| 101 | must be less than one day). Most implementations of |
| 102 | <tt class="method">utcoffset()</tt> will probably look like one of these two: |
| 103 | |
| 104 | <P> |
| 105 | <div class="verbatim"><pre> |
| 106 | return CONSTANT # fixed-offset class |
| 107 | return CONSTANT + self.dst(dt) # daylight-aware class |
| 108 | </pre></div> |
| 109 | |
| 110 | <P> |
| 111 | If <tt class="method">utcoffset()</tt> does not return <code>None</code>, |
| 112 | <tt class="method">dst()</tt> should not return <code>None</code> either. |
| 113 | |
| 114 | <P> |
| 115 | The default implementation of <tt class="method">utcoffset()</tt> raises |
| 116 | <tt class="exception">NotImplementedError</tt>. |
| 117 | </dl> |
| 118 | |
| 119 | <P> |
| 120 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 121 | <td><nobr><b><tt id='l2h-1941' xml:id='l2h-1941' class="method">dst</tt></b>(</nobr></td> |
| 122 | <td><var>self, dt</var>)</td></tr></table></dt> |
| 123 | <dd> |
| 124 | Return the daylight saving time (DST) adjustment, in minutes east of |
| 125 | UTC, or <code>None</code> if DST information isn't known. Return |
| 126 | <code>timedelta(0)</code> if DST is not in effect. |
| 127 | If DST is in effect, return the offset as a |
| 128 | <tt class="class">timedelta</tt> object (see <tt class="method">utcoffset()</tt> for details). |
| 129 | Note that DST offset, if applicable, has |
| 130 | already been added to the UTC offset returned by |
| 131 | <tt class="method">utcoffset()</tt>, so there's no need to consult <tt class="method">dst()</tt> |
| 132 | unless you're interested in obtaining DST info separately. For |
| 133 | example, <tt class="method">datetime.timetuple()</tt> calls its <tt class="member">tzinfo</tt> |
| 134 | member's <tt class="method">dst()</tt> method to determine how the |
| 135 | <tt class="member">tm_isdst</tt> flag should be set, and |
| 136 | <tt class="method">tzinfo.fromutc()</tt> calls <tt class="method">dst()</tt> to account for |
| 137 | DST changes when crossing time zones. |
| 138 | |
| 139 | <P> |
| 140 | An instance <var>tz</var> of a <tt class="class">tzinfo</tt> subclass that models both |
| 141 | standard and daylight times must be consistent in this sense: |
| 142 | |
| 143 | <P> |
| 144 | <code><var>tz</var>.utcoffset(<var>dt</var>) - <var>tz</var>.dst(<var>dt</var>)</code> |
| 145 | |
| 146 | <P> |
| 147 | must return the same result for every <tt class="class">datetime</tt> <var>dt</var> |
| 148 | with <code><var>dt</var>.tzinfo == <var>tz</var></code> For sane <tt class="class">tzinfo</tt> |
| 149 | subclasses, this expression yields the time zone's "standard offset", |
| 150 | which should not depend on the date or the time, but only on geographic |
| 151 | location. The implementation of <tt class="method">datetime.astimezone()</tt> relies |
| 152 | on this, but cannot detect violations; it's the programmer's |
| 153 | responsibility to ensure it. If a <tt class="class">tzinfo</tt> subclass cannot |
| 154 | guarantee this, it may be able to override the default implementation |
| 155 | of <tt class="method">tzinfo.fromutc()</tt> to work correctly with <tt class="method">astimezone()</tt> |
| 156 | regardless. |
| 157 | |
| 158 | <P> |
| 159 | Most implementations of <tt class="method">dst()</tt> will probably look like one |
| 160 | of these two: |
| 161 | |
| 162 | <P> |
| 163 | <div class="verbatim"><pre> |
| 164 | def dst(self): |
| 165 | # a fixed-offset class: doesn't account for DST |
| 166 | return timedelta(0) |
| 167 | </pre></div> |
| 168 | |
| 169 | <P> |
| 170 | or |
| 171 | |
| 172 | <P> |
| 173 | <div class="verbatim"><pre> |
| 174 | def dst(self): |
| 175 | # Code to set dston and dstoff to the time zone's DST |
| 176 | # transition times based on the input dt.year, and expressed |
| 177 | # in standard local time. Then |
| 178 | |
| 179 | if dston <= dt.replace(tzinfo=None) < dstoff: |
| 180 | return timedelta(hours=1) |
| 181 | else: |
| 182 | return timedelta(0) |
| 183 | </pre></div> |
| 184 | |
| 185 | <P> |
| 186 | The default implementation of <tt class="method">dst()</tt> raises |
| 187 | <tt class="exception">NotImplementedError</tt>. |
| 188 | </dl> |
| 189 | |
| 190 | <P> |
| 191 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 192 | <td><nobr><b><tt id='l2h-1942' xml:id='l2h-1942' class="method">tzname</tt></b>(</nobr></td> |
| 193 | <td><var>self, dt</var>)</td></tr></table></dt> |
| 194 | <dd> |
| 195 | Return the time zone name corresponding to the <tt class="class">datetime</tt> |
| 196 | object <var>dt</var>, as a string. |
| 197 | Nothing about string names is defined by the |
| 198 | <tt class="module">datetime</tt> module, and there's no requirement that it mean |
| 199 | anything in particular. For example, "GMT", "UTC", "-500", "-5:00", |
| 200 | "EDT", "US/Eastern", "America/New York" are all valid replies. Return |
| 201 | <code>None</code> if a string name isn't known. Note that this is a method |
| 202 | rather than a fixed string primarily because some <tt class="class">tzinfo</tt> |
| 203 | subclasses will wish to return different names depending on the specific |
| 204 | value of <var>dt</var> passed, especially if the <tt class="class">tzinfo</tt> class is |
| 205 | accounting for daylight time. |
| 206 | |
| 207 | <P> |
| 208 | The default implementation of <tt class="method">tzname()</tt> raises |
| 209 | <tt class="exception">NotImplementedError</tt>. |
| 210 | </dl> |
| 211 | |
| 212 | <P> |
| 213 | These methods are called by a <tt class="class">datetime</tt> or <tt class="class">time</tt> object, |
| 214 | in response to their methods of the same names. A <tt class="class">datetime</tt> |
| 215 | object passes itself as the argument, and a <tt class="class">time</tt> object passes |
| 216 | <code>None</code> as the argument. A <tt class="class">tzinfo</tt> subclass's methods should |
| 217 | therefore be prepared to accept a <var>dt</var> argument of <code>None</code>, or of |
| 218 | class <tt class="class">datetime</tt>. |
| 219 | |
| 220 | <P> |
| 221 | When <code>None</code> is passed, it's up to the class designer to decide the |
| 222 | best response. For example, returning <code>None</code> is appropriate if the |
| 223 | class wishes to say that time objects don't participate in the |
| 224 | <tt class="class">tzinfo</tt> protocols. It may be more useful for <code>utcoffset(None)</code> |
| 225 | to return the standard UTC offset, as there is no other convention for |
| 226 | discovering the standard offset. |
| 227 | |
| 228 | <P> |
| 229 | When a <tt class="class">datetime</tt> object is passed in response to a |
| 230 | <tt class="class">datetime</tt> method, <code>dt.tzinfo</code> is the same object as |
| 231 | <var>self</var>. <tt class="class">tzinfo</tt> methods can rely on this, unless |
| 232 | user code calls <tt class="class">tzinfo</tt> methods directly. The intent is that |
| 233 | the <tt class="class">tzinfo</tt> methods interpret <var>dt</var> as being in local time, |
| 234 | and not need worry about objects in other timezones. |
| 235 | |
| 236 | <P> |
| 237 | There is one more <tt class="class">tzinfo</tt> method that a subclass may wish to |
| 238 | override: |
| 239 | |
| 240 | <P> |
| 241 | <dl><dt><table cellpadding="0" cellspacing="0"><tr valign="baseline"> |
| 242 | <td><nobr><b><tt id='l2h-1943' xml:id='l2h-1943' class="method">fromutc</tt></b>(</nobr></td> |
| 243 | <td><var>self, dt</var>)</td></tr></table></dt> |
| 244 | <dd> |
| 245 | This is called from the default <tt class="class">datetime.astimezone()</tt> |
| 246 | implementation. When called from that, <code><var>dt</var>.tzinfo</code> is |
| 247 | <var>self</var>, and <var>dt</var>'s date and time members are to be viewed as |
| 248 | expressing a UTC time. The purpose of <tt class="method">fromutc()</tt> is to |
| 249 | adjust the date and time members, returning an equivalent datetime in |
| 250 | <var>self</var>'s local time. |
| 251 | |
| 252 | <P> |
| 253 | Most <tt class="class">tzinfo</tt> subclasses should be able to inherit the default |
| 254 | <tt class="method">fromutc()</tt> implementation without problems. It's strong enough |
| 255 | to handle fixed-offset time zones, and time zones accounting for both |
| 256 | standard and daylight time, and the latter even if the DST transition |
| 257 | times differ in different years. An example of a time zone the default |
| 258 | <tt class="method">fromutc()</tt> implementation may not handle correctly in all cases |
| 259 | is one where the standard offset (from UTC) depends on the specific date |
| 260 | and time passed, which can happen for political reasons. |
| 261 | The default implementations of <tt class="method">astimezone()</tt> and |
| 262 | <tt class="method">fromutc()</tt> may not produce the result you want if the result is |
| 263 | one of the hours straddling the moment the standard offset changes. |
| 264 | |
| 265 | <P> |
| 266 | Skipping code for error cases, the default <tt class="method">fromutc()</tt> |
| 267 | implementation acts like: |
| 268 | |
| 269 | <P> |
| 270 | <div class="verbatim"><pre> |
| 271 | def fromutc(self, dt): |
| 272 | # raise ValueError error if dt.tzinfo is not self |
| 273 | dtoff = dt.utcoffset() |
| 274 | dtdst = dt.dst() |
| 275 | # raise ValueError if dtoff is None or dtdst is None |
| 276 | delta = dtoff - dtdst # this is self's standard offset |
| 277 | if delta: |
| 278 | dt += delta # convert to standard local time |
| 279 | dtdst = dt.dst() |
| 280 | # raise ValueError if dtdst is None |
| 281 | if dtdst: |
| 282 | return dt + dtdst |
| 283 | else: |
| 284 | return dt |
| 285 | </pre></div> |
| 286 | </dl> |
| 287 | |
| 288 | <P> |
| 289 | Example <tt class="class">tzinfo</tt> classes: |
| 290 | |
| 291 | <P> |
| 292 | <div class="verbatim"> |
| 293 | <pre>from datetime import tzinfo, timedelta, datetime |
| 294 | |
| 295 | ZERO = timedelta(0) |
| 296 | HOUR = timedelta(hours=1) |
| 297 | |
| 298 | # A UTC class. |
| 299 | |
| 300 | class UTC(tzinfo): |
| 301 | """UTC""" |
| 302 | |
| 303 | def utcoffset(self, dt): |
| 304 | return ZERO |
| 305 | |
| 306 | def tzname(self, dt): |
| 307 | return "UTC" |
| 308 | |
| 309 | def dst(self, dt): |
| 310 | return ZERO |
| 311 | |
| 312 | utc = UTC() |
| 313 | |
| 314 | # A class building tzinfo objects for fixed-offset time zones. |
| 315 | # Note that FixedOffset(0, "UTC") is a different way to build a |
| 316 | # UTC tzinfo object. |
| 317 | |
| 318 | class FixedOffset(tzinfo): |
| 319 | """Fixed offset in minutes east from UTC.""" |
| 320 | |
| 321 | def __init__(self, offset, name): |
| 322 | self.__offset = timedelta(minutes = offset) |
| 323 | self.__name = name |
| 324 | |
| 325 | def utcoffset(self, dt): |
| 326 | return self.__offset |
| 327 | |
| 328 | def tzname(self, dt): |
| 329 | return self.__name |
| 330 | |
| 331 | def dst(self, dt): |
| 332 | return ZERO |
| 333 | |
| 334 | # A class capturing the platform's idea of local time. |
| 335 | |
| 336 | import time as _time |
| 337 | |
| 338 | STDOFFSET = timedelta(seconds = -_time.timezone) |
| 339 | if _time.daylight: |
| 340 | DSTOFFSET = timedelta(seconds = -_time.altzone) |
| 341 | else: |
| 342 | DSTOFFSET = STDOFFSET |
| 343 | |
| 344 | DSTDIFF = DSTOFFSET - STDOFFSET |
| 345 | |
| 346 | class LocalTimezone(tzinfo): |
| 347 | |
| 348 | def utcoffset(self, dt): |
| 349 | if self._isdst(dt): |
| 350 | return DSTOFFSET |
| 351 | else: |
| 352 | return STDOFFSET |
| 353 | |
| 354 | def dst(self, dt): |
| 355 | if self._isdst(dt): |
| 356 | return DSTDIFF |
| 357 | else: |
| 358 | return ZERO |
| 359 | |
| 360 | def tzname(self, dt): |
| 361 | return _time.tzname[self._isdst(dt)] |
| 362 | |
| 363 | def _isdst(self, dt): |
| 364 | tt = (dt.year, dt.month, dt.day, |
| 365 | dt.hour, dt.minute, dt.second, |
| 366 | dt.weekday(), 0, -1) |
| 367 | stamp = _time.mktime(tt) |
| 368 | tt = _time.localtime(stamp) |
| 369 | return tt.tm_isdst > 0 |
| 370 | |
| 371 | Local = LocalTimezone() |
| 372 | |
| 373 | # A complete implementation of current DST rules for major US time zones. |
| 374 | |
| 375 | def first_sunday_on_or_after(dt): |
| 376 | days_to_go = 6 - dt.weekday() |
| 377 | if days_to_go: |
| 378 | dt += timedelta(days_to_go) |
| 379 | return dt |
| 380 | |
| 381 | # In the US, DST starts at 2am (standard time) on the first Sunday in April. |
| 382 | DSTSTART = datetime(1, 4, 1, 2) |
| 383 | # and ends at 2am (DST time; 1am standard time) on the last Sunday of Oct. |
| 384 | # which is the first Sunday on or after Oct 25. |
| 385 | DSTEND = datetime(1, 10, 25, 1) |
| 386 | |
| 387 | class USTimeZone(tzinfo): |
| 388 | |
| 389 | def __init__(self, hours, reprname, stdname, dstname): |
| 390 | self.stdoffset = timedelta(hours=hours) |
| 391 | self.reprname = reprname |
| 392 | self.stdname = stdname |
| 393 | self.dstname = dstname |
| 394 | |
| 395 | def __repr__(self): |
| 396 | return self.reprname |
| 397 | |
| 398 | def tzname(self, dt): |
| 399 | if self.dst(dt): |
| 400 | return self.dstname |
| 401 | else: |
| 402 | return self.stdname |
| 403 | |
| 404 | def utcoffset(self, dt): |
| 405 | return self.stdoffset + self.dst(dt) |
| 406 | |
| 407 | def dst(self, dt): |
| 408 | if dt is None or dt.tzinfo is None: |
| 409 | # An exception may be sensible here, in one or both cases. |
| 410 | # It depends on how you want to treat them. The default |
| 411 | # fromutc() implementation (called by the default astimezone() |
| 412 | # implementation) passes a datetime with dt.tzinfo is self. |
| 413 | return ZERO |
| 414 | assert dt.tzinfo is self |
| 415 | |
| 416 | # Find first Sunday in April & the last in October. |
| 417 | start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year)) |
| 418 | end = first_sunday_on_or_after(DSTEND.replace(year=dt.year)) |
| 419 | |
| 420 | # Can't compare naive to aware objects, so strip the timezone from |
| 421 | # dt first. |
| 422 | if start <= dt.replace(tzinfo=None) < end: |
| 423 | return HOUR |
| 424 | else: |
| 425 | return ZERO |
| 426 | |
| 427 | Eastern = USTimeZone(-5, "Eastern", "EST", "EDT") |
| 428 | Central = USTimeZone(-6, "Central", "CST", "CDT") |
| 429 | Mountain = USTimeZone(-7, "Mountain", "MST", "MDT") |
| 430 | Pacific = USTimeZone(-8, "Pacific", "PST", "PDT") |
| 431 | </pre> |
| 432 | <div class="footer"> |
| 433 | <a href="tzinfo-examples.txt" type="text/plain">Download as text (original file name: <span class="file">tzinfo-examples.py</span>).</a> |
| 434 | </div></div> |
| 435 | |
| 436 | <P> |
| 437 | Note that there are unavoidable subtleties twice per year in a |
| 438 | <tt class="class">tzinfo</tt> |
| 439 | subclass accounting for both standard and daylight time, at the DST |
| 440 | transition points. For concreteness, consider US Eastern (UTC -0500), |
| 441 | where EDT begins the minute after 1:59 (EST) on the first Sunday in |
| 442 | April, and ends the minute after 1:59 (EDT) on the last Sunday in October: |
| 443 | |
| 444 | <P> |
| 445 | <div class="verbatim"><pre> |
| 446 | UTC 3:MM 4:MM 5:MM 6:MM 7:MM 8:MM |
| 447 | EST 22:MM 23:MM 0:MM 1:MM 2:MM 3:MM |
| 448 | EDT 23:MM 0:MM 1:MM 2:MM 3:MM 4:MM |
| 449 | |
| 450 | start 22:MM 23:MM 0:MM 1:MM 3:MM 4:MM |
| 451 | |
| 452 | end 23:MM 0:MM 1:MM 1:MM 2:MM 3:MM |
| 453 | </pre></div> |
| 454 | |
| 455 | <P> |
| 456 | When DST starts (the "start" line), the local wall clock leaps from 1:59 |
| 457 | to 3:00. A wall time of the form 2:MM doesn't really make sense on that |
| 458 | day, so <code>astimezone(Eastern)</code> won't deliver a result with |
| 459 | <code>hour == 2</code> on the |
| 460 | day DST begins. In order for <tt class="method">astimezone()</tt> to make this |
| 461 | guarantee, the <tt class="method">rzinfo.dst()</tt> method must consider times |
| 462 | in the "missing hour" (2:MM for Eastern) to be in daylight time. |
| 463 | |
| 464 | <P> |
| 465 | When DST ends (the "end" line), there's a potentially worse problem: |
| 466 | there's an hour that can't be spelled unambiguously in local wall time: |
| 467 | the last hour of daylight time. In Eastern, that's times of |
| 468 | the form 5:MM UTC on the day daylight time ends. The local wall clock |
| 469 | leaps from 1:59 (daylight time) back to 1:00 (standard time) again. |
| 470 | Local times of the form 1:MM are ambiguous. <tt class="method">astimezone()</tt> mimics |
| 471 | the local clock's behavior by mapping two adjacent UTC hours into the |
| 472 | same local hour then. In the Eastern example, UTC times of the form |
| 473 | 5:MM and 6:MM both map to 1:MM when converted to Eastern. In order for |
| 474 | <tt class="method">astimezone()</tt> to make this guarantee, the <tt class="method">tzinfo.dst()</tt> |
| 475 | method must consider times in the "repeated hour" to be in |
| 476 | standard time. This is easily arranged, as in the example, by expressing |
| 477 | DST switch times in the time zone's standard local time. |
| 478 | |
| 479 | <P> |
| 480 | Applications that can't bear such ambiguities should avoid using hybrid |
| 481 | <tt class="class">tzinfo</tt> subclasses; there are no ambiguities when using UTC, or |
| 482 | any other fixed-offset <tt class="class">tzinfo</tt> subclass (such as a class |
| 483 | representing only EST (fixed offset -5 hours), or only EDT (fixed offset |
| 484 | -4 hours)). |
| 485 | |
| 486 | <P> |
| 487 | |
| 488 | <DIV CLASS="navigation"> |
| 489 | <div class='online-navigation'> |
| 490 | <p></p><hr /> |
| 491 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> |
| 492 | <tr> |
| 493 | <td class='online-navigation'><a rel="prev" title="6.10.5 time Objects" |
| 494 | href="datetime-time.html"><img src='../icons/previous.png' |
| 495 | border='0' height='32' alt='Previous Page' width='32' /></A></td> |
| 496 | <td class='online-navigation'><a rel="parent" title="6.10 datetime " |
| 497 | href="module-datetime.html"><img src='../icons/up.png' |
| 498 | border='0' height='32' alt='Up One Level' width='32' /></A></td> |
| 499 | <td class='online-navigation'><a rel="next" title="6.10.7 strftime() Behavior" |
| 500 | href="node257.html"><img src='../icons/next.png' |
| 501 | border='0' height='32' alt='Next Page' width='32' /></A></td> |
| 502 | <td align="center" width="100%">Python Library Reference</td> |
| 503 | <td class='online-navigation'><a rel="contents" title="Table of Contents" |
| 504 | href="contents.html"><img src='../icons/contents.png' |
| 505 | border='0' height='32' alt='Contents' width='32' /></A></td> |
| 506 | <td class='online-navigation'><a href="modindex.html" title="Module Index"><img src='../icons/modules.png' |
| 507 | border='0' height='32' alt='Module Index' width='32' /></a></td> |
| 508 | <td class='online-navigation'><a rel="index" title="Index" |
| 509 | href="genindex.html"><img src='../icons/index.png' |
| 510 | border='0' height='32' alt='Index' width='32' /></A></td> |
| 511 | </tr></table> |
| 512 | <div class='online-navigation'> |
| 513 | <b class="navlabel">Previous:</b> |
| 514 | <a class="sectref" rel="prev" href="datetime-time.html">6.10.5 time Objects</A> |
| 515 | <b class="navlabel">Up:</b> |
| 516 | <a class="sectref" rel="parent" href="module-datetime.html">6.10 datetime </A> |
| 517 | <b class="navlabel">Next:</b> |
| 518 | <a class="sectref" rel="next" href="node257.html">6.10.7 strftime() Behavior</A> |
| 519 | </div> |
| 520 | </div> |
| 521 | <hr /> |
| 522 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> |
| 523 | </DIV> |
| 524 | <!--End of Navigation Panel--> |
| 525 | <ADDRESS> |
| 526 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. |
| 527 | </ADDRESS> |
| 528 | </BODY> |
| 529 | </HTML> |