Back to index

python3.2  3.2.2
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes
datetime.timezone Class Reference
Inheritance diagram for datetime.timezone:
Inheritance graph
[legend]
Collaboration diagram for datetime.timezone:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __new__
def __getinitargs__
def __eq__
def __hash__
def __repr__
def __str__
def utcoffset
def tzname
def dst
def fromutc
def __reduce__

Private Member Functions

def _create

Static Private Member Functions

def _name_from_offset

Private Attributes

 _offset
 _name

Static Private Attributes

string __slots__ = '_offset'
tuple _Omitted = object()
tuple _maxoffset = timedelta(hours=23, minutes=59)
 _minoffset = -_maxoffset

Detailed Description

Definition at line 1786 of file datetime.py.


Member Function Documentation

def datetime.timezone.__eq__ (   self,
  other 
)

Definition at line 1823 of file datetime.py.

01823 
01824     def __eq__(self, other):
01825         return self._offset == other._offset

Here is the caller graph for this function:

pickle support

Definition at line 1817 of file datetime.py.

01817 
01818     def __getinitargs__(self):
01819         """pickle support"""
01820         if self._name is None:
01821             return (self._offset,)
01822         return (self._offset, self._name)

Definition at line 1826 of file datetime.py.

01826 
01827     def __hash__(self):
01828         return hash(self._offset)

def datetime.timezone.__new__ (   cls,
  offset,
  name = _Omitted 
)

Definition at line 1791 of file datetime.py.

01791 
01792     def __new__(cls, offset, name=_Omitted):
01793         if not isinstance(offset, timedelta):
01794             raise TypeError("offset must be a timedelta")
01795         if name is cls._Omitted:
01796             if not offset:
01797                 return cls.utc
01798             name = None
01799         elif not isinstance(name, str):
01800             raise TypeError("name must be a string")
01801         if not cls._minoffset <= offset <= cls._maxoffset:
01802             raise ValueError("offset must be a timedelta"
01803                              " strictly between -timedelta(hours=24) and"
01804                              " timedelta(hours=24).")
01805         if (offset.microseconds != 0 or
01806             offset.seconds % 60 != 0):
01807             raise ValueError("offset must be a timedelta"
01808                              " representing a whole number of minutes")
01809         return cls._create(offset, name)

def datetime.tzinfo.__reduce__ (   self) [inherited]

Definition at line 975 of file datetime.py.

00975 
00976     def __reduce__(self):
00977         getinitargs = getattr(self, "__getinitargs__", None)
00978         if getinitargs:
00979             args = getinitargs()
00980         else:
00981             args = ()
00982         getstate = getattr(self, "__getstate__", None)
00983         if getstate:
00984             state = getstate()
00985         else:
00986             state = getattr(self, "__dict__", None) or None
00987         if state is None:
00988             return (self.__class__, args)
00989         else:
00990             return (self.__class__, args, state)

Here is the call graph for this function:

Convert to formal string, for repr().

>>> tz = timezone.utc
>>> repr(tz)
'datetime.timezone.utc'
>>> tz = timezone(timedelta(hours=-5), 'EST')
>>> repr(tz)
"datetime.timezone(datetime.timedelta(-1, 68400), 'EST')"

Definition at line 1829 of file datetime.py.

01829 
01830     def __repr__(self):
01831         """Convert to formal string, for repr().
01832 
01833         >>> tz = timezone.utc
01834         >>> repr(tz)
01835         'datetime.timezone.utc'
01836         >>> tz = timezone(timedelta(hours=-5), 'EST')
01837         >>> repr(tz)
01838         "datetime.timezone(datetime.timedelta(-1, 68400), 'EST')"
01839         """
01840         if self is self.utc:
01841             return 'datetime.timezone.utc'
01842         if self._name is None:
01843             return "%s(%r)" % ('datetime.' + self.__class__.__name__,
01844                                self._offset)
01845         return "%s(%r, %r)" % ('datetime.' + self.__class__.__name__,
01846                                self._offset, self._name)

def datetime.timezone.__str__ (   self)

Definition at line 1847 of file datetime.py.

01847 
01848     def __str__(self):
01849         return self.tzname(None)

Here is the call graph for this function:

Here is the caller graph for this function:

def datetime.timezone._create (   cls,
  offset,
  name = None 
) [private]

Definition at line 1811 of file datetime.py.

01811 
01812     def _create(cls, offset, name=None):
01813         self = tzinfo.__new__(cls)
01814         self._offset = offset
01815         self._name = name
01816         return self

Here is the caller graph for this function:

def datetime.timezone._name_from_offset (   delta) [static, private]

Definition at line 1883 of file datetime.py.

01883 
01884     def _name_from_offset(delta):
01885         if delta < timedelta(0):
01886             sign = '-'
01887             delta = -delta
01888         else:
01889             sign = '+'
01890         hours, rest = divmod(delta, timedelta(hours=1))
01891         minutes = rest // timedelta(minutes=1)
01892         return 'UTC{}{:02d}:{:02d}'.format(sign, hours, minutes)
01893 
01894 timezone.utc = timezone._create(timedelta(0))
01895 timezone.min = timezone._create(timezone._minoffset)
01896 timezone.max = timezone._create(timezone._maxoffset)
01897 
01898 """
01899 Some time zone algebra.  For a datetime x, let
01900     x.n = x stripped of its timezone -- its naive time.
01901     x.o = x.utcoffset(), and assuming that doesn't raise an exception or
01902           return None
01903     x.d = x.dst(), and assuming that doesn't raise an exception or
01904           return None
01905     x.s = x's standard offset, x.o - x.d
01906 
01907 Now some derived rules, where k is a duration (timedelta).
01908 
01909 1. x.o = x.s + x.d
01910    This follows from the definition of x.s.
01911 
01912 2. If x and y have the same tzinfo member, x.s = y.s.
01913    This is actually a requirement, an assumption we need to make about
01914    sane tzinfo classes.
01915 
01916 3. The naive UTC time corresponding to x is x.n - x.o.
01917    This is again a requirement for a sane tzinfo class.
01918 
01919 4. (x+k).s = x.s
01920    This follows from #2, and that datimetimetz+timedelta preserves tzinfo.
01921 
01922 5. (x+k).n = x.n + k
01923    Again follows from how arithmetic is defined.
01924 
01925 Now we can explain tz.fromutc(x).  Let's assume it's an interesting case
01926 (meaning that the various tzinfo methods exist, and don't blow up or return
01927 None when called).
01928 
01929 The function wants to return a datetime y with timezone tz, equivalent to x.
01930 x is already in UTC.
01931 
01932 By #3, we want
01933 
01934     y.n - y.o = x.n                             [1]
01935 
01936 The algorithm starts by attaching tz to x.n, and calling that y.  So
01937 x.n = y.n at the start.  Then it wants to add a duration k to y, so that [1]
01938 becomes true; in effect, we want to solve [2] for k:
01939 
01940    (y+k).n - (y+k).o = x.n                      [2]
01941 
01942 By #1, this is the same as
01943 
01944    (y+k).n - ((y+k).s + (y+k).d) = x.n          [3]
01945 
01946 By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start.
01947 Substituting that into [3],
01948 
01949    x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving
01950    k - (y+k).s - (y+k).d = 0; rearranging,
01951    k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so
01952    k = y.s - (y+k).d
01953 
01954 On the RHS, (y+k).d can't be computed directly, but y.s can be, and we
01955 approximate k by ignoring the (y+k).d term at first.  Note that k can't be
01956 very large, since all offset-returning methods return a duration of magnitude
01957 less than 24 hours.  For that reason, if y is firmly in std time, (y+k).d must
01958 be 0, so ignoring it has no consequence then.
01959 
01960 In any case, the new value is
01961 
01962     z = y + y.s                                 [4]
01963 
01964 It's helpful to step back at look at [4] from a higher level:  it's simply
01965 mapping from UTC to tz's standard time.
01966 
01967 At this point, if
01968 
01969     z.n - z.o = x.n                             [5]
01970 
01971 we have an equivalent time, and are almost done.  The insecurity here is
01972 at the start of daylight time.  Picture US Eastern for concreteness.  The wall
01973 time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good
01974 sense then.  The docs ask that an Eastern tzinfo class consider such a time to
01975 be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST
01976 on the day DST starts.  We want to return the 1:MM EST spelling because that's
01977 the only spelling that makes sense on the local wall clock.
01978 
01979 In fact, if [5] holds at this point, we do have the standard-time spelling,
01980 but that takes a bit of proof.  We first prove a stronger result.  What's the
01981 difference between the LHS and RHS of [5]?  Let
01982 
01983     diff = x.n - (z.n - z.o)                    [6]
01984 
01985 Now
01986     z.n =                       by [4]
01987     (y + y.s).n =               by #5
01988     y.n + y.s =                 since y.n = x.n
01989     x.n + y.s =                 since z and y are have the same tzinfo member,
01990                                     y.s = z.s by #2
01991     x.n + z.s
01992 
01993 Plugging that back into [6] gives
01994 
01995     diff =
01996     x.n - ((x.n + z.s) - z.o) =     expanding
01997     x.n - x.n - z.s + z.o =         cancelling
01998     - z.s + z.o =                   by #2
01999     z.d
02000 
02001 So diff = z.d.
02002 
02003 If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time
02004 spelling we wanted in the endcase described above.  We're done.  Contrarily,
02005 if z.d = 0, then we have a UTC equivalent, and are also done.
02006 
02007 If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to
02008 add to z (in effect, z is in tz's standard time, and we need to shift the
02009 local clock into tz's daylight time).
02010 
02011 Let
02012 
02013     z' = z + z.d = z + diff                     [7]
02014 
02015 and we can again ask whether
02016 
02017     z'.n - z'.o = x.n                           [8]
02018 
02019 If so, we're done.  If not, the tzinfo class is insane, according to the
02020 assumptions we've made.  This also requires a bit of proof.  As before, let's
02021 compute the difference between the LHS and RHS of [8] (and skipping some of
02022 the justifications for the kinds of substitutions we've done several times
02023 already):
02024 
02025     diff' = x.n - (z'.n - z'.o) =           replacing z'.n via [7]
02026             x.n  - (z.n + diff - z'.o) =    replacing diff via [6]
02027             x.n - (z.n + x.n - (z.n - z.o) - z'.o) =
02028             x.n - z.n - x.n + z.n - z.o + z'.o =    cancel x.n
02029             - z.n + z.n - z.o + z'.o =              cancel z.n
02030             - z.o + z'.o =                      #1 twice
02031             -z.s - z.d + z'.s + z'.d =          z and z' have same tzinfo
02032             z'.d - z.d
02033 
02034 So z' is UTC-equivalent to x iff z'.d = z.d at this point.  If they are equal,
02035 we've found the UTC-equivalent so are done.  In fact, we stop with [7] and
02036 return z', not bothering to compute z'.d.
02037 
02038 How could z.d and z'd differ?  z' = z + z.d [7], so merely moving z' by
02039 a dst() offset, and starting *from* a time already in DST (we know z.d != 0),
02040 would have to change the result dst() returns:  we start in DST, and moving
02041 a little further into it takes us out of DST.
02042 
02043 There isn't a sane case where this can happen.  The closest it gets is at
02044 the end of DST, where there's an hour in UTC with no spelling in a hybrid
02045 tzinfo class.  In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT.  During
02046 that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM
02047 UTC) because the docs insist on that, but 0:MM is taken as being in daylight
02048 time (4:MM UTC).  There is no local time mapping to 5:MM UTC.  The local
02049 clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in
02050 standard time.  Since that's what the local clock *does*, we want to map both
02051 UTC hours 5:MM and 6:MM to 1:MM Eastern.  The result is ambiguous
02052 in local time, but so it goes -- it's the way the local clock works.
02053 
02054 When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0,
02055 so z=0:MM.  z.d=60 (minutes) then, so [5] doesn't hold and we keep going.
02056 z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8]
02057 (correctly) concludes that z' is not UTC-equivalent to x.
02058 
02059 Because we know z.d said z was in daylight time (else [5] would have held and
02060 we would have stopped then), and we know z.d != z'.d (else [8] would have held
02061 and we we have stopped then), and there are only 2 possible values dst() can
02062 return in Eastern, it follows that z'.d must be 0 (which it is in the example,
02063 but the reasoning doesn't depend on the example -- it depends on there being
02064 two possible dst() outcomes, one zero and the other non-zero).  Therefore
02065 z' must be in standard time, and is the spelling we want in this case.
02066 
02067 Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is
02068 concerned (because it takes z' as being in standard time rather than the
02069 daylight time we intend here), but returning it gives the real-life "local
02070 clock repeats an hour" behavior when mapping the "unspellable" UTC hour into
02071 tz.
02072 
02073 When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with
02074 the 1:MM standard time spelling we want.
02075 
02076 So how can this break?  One of the assumptions must be violated.  Two
02077 possibilities:
02078 
02079 1) [2] effectively says that y.s is invariant across all y belong to a given
02080    time zone.  This isn't true if, for political reasons or continental drift,
02081    a region decides to change its base offset from UTC.
02082 
02083 2) There may be versions of "double daylight" time where the tail end of
02084    the analysis gives up a step too early.  I haven't thought about that
02085    enough to say.
02086 
02087 In any case, it's clear that the default fromutc() is strong enough to handle
02088 "almost all" time zones:  so long as the standard offset is invariant, it
02089 doesn't matter if daylight time transition points change from year to year, or
02090 if daylight time is skipped in some years; it doesn't matter how large or
02091 small dst() may get within its bounds; and it doesn't even matter if some
02092 perverse time zone returns a negative dst()).  So a breaking case must be
02093 pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
02094 """
try:

Here is the call graph for this function:

Here is the caller graph for this function:

def datetime.timezone.dst (   self,
  dt 
)
datetime -> DST offset in minutes east of UTC.

Return 0 if DST not in effect.  utcoffset() must include the DST
offset.

Reimplemented from datetime.tzinfo.

Definition at line 1864 of file datetime.py.

01864 
01865     def dst(self, dt):
01866         if isinstance(dt, datetime) or dt is None:
01867             return None
01868         raise TypeError("dst() argument must be a datetime instance"
01869                         " or None")

def datetime.timezone.fromutc (   self,
  dt 
)

Reimplemented from datetime.tzinfo.

Definition at line 1870 of file datetime.py.

01870 
01871     def fromutc(self, dt):
01872         if isinstance(dt, datetime):
01873             if dt.tzinfo is not self:
01874                 raise ValueError("fromutc: dt.tzinfo "
01875                                  "is not self")
01876             return dt + self._offset
01877         raise TypeError("fromutc() argument must be a datetime instance"
01878                         " or None")

def datetime.timezone.tzname (   self,
  dt 
)

Reimplemented from datetime.tzinfo.

Definition at line 1856 of file datetime.py.

01856 
01857     def tzname(self, dt):
01858         if isinstance(dt, datetime) or dt is None:
01859             if self._name is None:
01860                 return self._name_from_offset(self._offset)
01861             return self._name
01862         raise TypeError("tzname() argument must be a datetime instance"
01863                         " or None")

Here is the call graph for this function:

def datetime.timezone.utcoffset (   self,
  dt 
)

Reimplemented from datetime.tzinfo.

Definition at line 1850 of file datetime.py.

01850 
01851     def utcoffset(self, dt):
01852         if isinstance(dt, datetime) or dt is None:
01853             return self._offset
01854         raise TypeError("utcoffset() argument must be a datetime instance"
01855                         " or None")


Member Data Documentation

Reimplemented from datetime.tzinfo.

Definition at line 1787 of file datetime.py.

tuple datetime.timezone._maxoffset = timedelta(hours=23, minutes=59) [static, private]

Definition at line 1879 of file datetime.py.

Definition at line 1880 of file datetime.py.

Definition at line 1814 of file datetime.py.

Definition at line 1813 of file datetime.py.

tuple datetime.timezone._Omitted = object() [static, private]

Definition at line 1790 of file datetime.py.


The documentation for this class was generated from the following file: