/Doc/includes/tzinfo-examples.py

http://unladen-swallow.googlecode.com/ · Python · 169 lines · 97 code · 38 blank · 34 comment · 17 complexity · 94356334411344df7806bb35f7ea1062 MD5 · raw file

  1. from datetime import tzinfo, timedelta, datetime
  2. ZERO = timedelta(0)
  3. HOUR = timedelta(hours=1)
  4. # A UTC class.
  5. class UTC(tzinfo):
  6. """UTC"""
  7. def utcoffset(self, dt):
  8. return ZERO
  9. def tzname(self, dt):
  10. return "UTC"
  11. def dst(self, dt):
  12. return ZERO
  13. utc = UTC()
  14. # A class building tzinfo objects for fixed-offset time zones.
  15. # Note that FixedOffset(0, "UTC") is a different way to build a
  16. # UTC tzinfo object.
  17. class FixedOffset(tzinfo):
  18. """Fixed offset in minutes east from UTC."""
  19. def __init__(self, offset, name):
  20. self.__offset = timedelta(minutes = offset)
  21. self.__name = name
  22. def utcoffset(self, dt):
  23. return self.__offset
  24. def tzname(self, dt):
  25. return self.__name
  26. def dst(self, dt):
  27. return ZERO
  28. # A class capturing the platform's idea of local time.
  29. import time as _time
  30. STDOFFSET = timedelta(seconds = -_time.timezone)
  31. if _time.daylight:
  32. DSTOFFSET = timedelta(seconds = -_time.altzone)
  33. else:
  34. DSTOFFSET = STDOFFSET
  35. DSTDIFF = DSTOFFSET - STDOFFSET
  36. class LocalTimezone(tzinfo):
  37. def utcoffset(self, dt):
  38. if self._isdst(dt):
  39. return DSTOFFSET
  40. else:
  41. return STDOFFSET
  42. def dst(self, dt):
  43. if self._isdst(dt):
  44. return DSTDIFF
  45. else:
  46. return ZERO
  47. def tzname(self, dt):
  48. return _time.tzname[self._isdst(dt)]
  49. def _isdst(self, dt):
  50. tt = (dt.year, dt.month, dt.day,
  51. dt.hour, dt.minute, dt.second,
  52. dt.weekday(), 0, -1)
  53. stamp = _time.mktime(tt)
  54. tt = _time.localtime(stamp)
  55. return tt.tm_isdst > 0
  56. Local = LocalTimezone()
  57. # A complete implementation of current DST rules for major US time zones.
  58. def first_sunday_on_or_after(dt):
  59. days_to_go = 6 - dt.weekday()
  60. if days_to_go:
  61. dt += timedelta(days_to_go)
  62. return dt
  63. # US DST Rules
  64. #
  65. # This is a simplified (i.e., wrong for a few cases) set of rules for US
  66. # DST start and end times. For a complete and up-to-date set of DST rules
  67. # and timezone definitions, visit the Olson Database (or try pytz):
  68. # http://www.twinsun.com/tz/tz-link.htm
  69. # http://sourceforge.net/projects/pytz/ (might not be up-to-date)
  70. #
  71. # In the US, since 2007, DST starts at 2am (standard time) on the second
  72. # Sunday in March, which is the first Sunday on or after Mar 8.
  73. DSTSTART_2007 = datetime(1, 3, 8, 2)
  74. # and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov.
  75. DSTEND_2007 = datetime(1, 11, 1, 1)
  76. # From 1987 to 2006, DST used to start at 2am (standard time) on the first
  77. # Sunday in April and to end at 2am (DST time; 1am standard time) on the last
  78. # Sunday of October, which is the first Sunday on or after Oct 25.
  79. DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
  80. DSTEND_1987_2006 = datetime(1, 10, 25, 1)
  81. # From 1967 to 1986, DST used to start at 2am (standard time) on the last
  82. # Sunday in April (the one on or after April 24) and to end at 2am (DST time;
  83. # 1am standard time) on the last Sunday of October, which is the first Sunday
  84. # on or after Oct 25.
  85. DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
  86. DSTEND_1967_1986 = DSTEND_1987_2006
  87. class USTimeZone(tzinfo):
  88. def __init__(self, hours, reprname, stdname, dstname):
  89. self.stdoffset = timedelta(hours=hours)
  90. self.reprname = reprname
  91. self.stdname = stdname
  92. self.dstname = dstname
  93. def __repr__(self):
  94. return self.reprname
  95. def tzname(self, dt):
  96. if self.dst(dt):
  97. return self.dstname
  98. else:
  99. return self.stdname
  100. def utcoffset(self, dt):
  101. return self.stdoffset + self.dst(dt)
  102. def dst(self, dt):
  103. if dt is None or dt.tzinfo is None:
  104. # An exception may be sensible here, in one or both cases.
  105. # It depends on how you want to treat them. The default
  106. # fromutc() implementation (called by the default astimezone()
  107. # implementation) passes a datetime with dt.tzinfo is self.
  108. return ZERO
  109. assert dt.tzinfo is self
  110. # Find start and end times for US DST. For years before 1967, return
  111. # ZERO for no DST.
  112. if 2006 < dt.year:
  113. dststart, dstend = DSTSTART_2007, DSTEND_2007
  114. elif 1986 < dt.year < 2007:
  115. dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
  116. elif 1966 < dt.year < 1987:
  117. dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
  118. else:
  119. return ZERO
  120. start = first_sunday_on_or_after(dststart.replace(year=dt.year))
  121. end = first_sunday_on_or_after(dstend.replace(year=dt.year))
  122. # Can't compare naive to aware objects, so strip the timezone from
  123. # dt first.
  124. if start <= dt.replace(tzinfo=None) < end:
  125. return HOUR
  126. else:
  127. return ZERO
  128. Eastern = USTimeZone(-5, "Eastern", "EST", "EDT")
  129. Central = USTimeZone(-6, "Central", "CST", "CDT")
  130. Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
  131. Pacific = USTimeZone(-8, "Pacific", "PST", "PDT")