summaryrefslogtreecommitdiff
path: root/src/pytz/tzinfo.py
diff options
context:
space:
mode:
authorStuart Bishop <stuart@stuartbishop.net>2008-10-08 22:45:33 +0700
committerStuart Bishop <stuart@stuartbishop.net>2008-10-08 22:45:33 +0700
commit8470f037ffef80c5e27106474b1a361c4ad3ef4e (patch)
tree2bdf1dd4291c7441bec3f4d886270d11f07371fc /src/pytz/tzinfo.py
parent73333df84850df2d28a1b81fa50cbc0d8eb8dffa (diff)
downloadpytz-8470f037ffef80c5e27106474b1a361c4ad3ef4e.tar.gz
Handle non-existant times during the start-of-DST transition and update docs
Diffstat (limited to 'src/pytz/tzinfo.py')
-rw-r--r--src/pytz/tzinfo.py69
1 files changed, 61 insertions, 8 deletions
diff --git a/src/pytz/tzinfo.py b/src/pytz/tzinfo.py
index c2f23c0..55afcb2 100644
--- a/src/pytz/tzinfo.py
+++ b/src/pytz/tzinfo.py
@@ -217,12 +217,6 @@ class DstTzInfo(BaseTzInfo):
Use is_dst=None to raise an AmbiguousTimeError for ambiguous
times at the end of daylight savings
- >>> try:
- ... loc_dt1 = amdam.localize(dt, is_dst=None)
- ... except AmbiguousTimeError:
- ... print 'Oops'
- Oops
-
>>> loc_dt1 = amdam.localize(dt, is_dst=None)
Traceback (most recent call last):
[...]
@@ -233,6 +227,27 @@ class DstTzInfo(BaseTzInfo):
>>> amdam.localize(dt) == amdam.localize(dt, False)
True
+ is_dst is also used to determine the correct timezone in the
+ wallclock times jumped over at the start of daylight savings time.
+
+ >>> pacific = timezone('US/Pacific')
+ >>> dt = datetime(2008, 3, 9, 2, 0, 0)
+ >>> ploc_dt1 = pacific.localize(dt, is_dst=True)
+ >>> ploc_dt2 = pacific.localize(dt, is_dst=False)
+ >>> ploc_dt1.strftime(fmt)
+ '2008-03-09 02:00:00 PDT (-0700)'
+ >>> ploc_dt2.strftime(fmt)
+ '2008-03-09 02:00:00 PST (-0800)'
+ >>> str(ploc_dt2 - ploc_dt1)
+ '1:00:00'
+
+ Use is_dst=None to raise a NonExistentTimeError for these skipped
+ times.
+
+ >>> loc_dt1 = pacific.localize(dt, is_dst=None)
+ Traceback (most recent call last):
+ [...]
+ NonExistentTimeError: 2008-03-09 02:00:00
'''
if dt.tzinfo is not None:
raise ValueError, 'Not naive datetime (tzinfo is already set)'
@@ -250,6 +265,31 @@ class DstTzInfo(BaseTzInfo):
if len(possible_loc_dt) == 1:
return possible_loc_dt.pop()
+ # If there are no possibly correct timezones, we are attempting
+ # to convert a time that never happened - the time period jumped
+ # during the start-of-DST transition period.
+ if len(possible_loc_dt) == 0:
+ # If we refuse to guess, raise an exception.
+ if is_dst is None:
+ raise NonExistentTimeError(dt)
+
+ # If we are forcing the pre-DST side of the DST transition, we
+ # obtain the correct timezone by winding the clock forward a few
+ # hours.
+ elif is_dst:
+ return self.localize(
+ dt + timedelta(hours=6), is_dst=True) - timedelta(hours=6)
+
+ # If we are forcing the post-DST side of the DST transition, we
+ # obtain the correct timezone by winding the clock back.
+ else:
+ return self.localize(
+ dt - timedelta(hours=6), is_dst=False) + timedelta(hours=6)
+
+
+ # If we get this far, we have multiple possible timezones - this
+ # is an ambiguous case occuring during the end-of-DST transition.
+
# If told to be strict, raise an exception since we have an
# ambiguous case
if is_dst is None:
@@ -322,7 +362,11 @@ class DstTzInfo(BaseTzInfo):
)
-class AmbiguousTimeError(Exception):
+class InvalidTimeError(Exception):
+ '''Base class for invalid time exceptions.'''
+
+
+class AmbiguousTimeError(InvalidTimeError):
'''Exception raised when attempting to create an ambiguous wallclock time.
At the end of a DST transition period, a particular wallclock time will
@@ -331,7 +375,16 @@ class AmbiguousTimeError(Exception):
See DstTzInfo.normalize() for more info
'''
-
+
+
+class NonExistentTimeError(InvalidTimeError):
+ '''Exception raised when attempting to create a wallclock time that
+ cannot exist.
+
+ At the start of a DST transition period, the wallclock time jumps forward.
+ The instants jumped over never occur.
+ '''
+
def unpickler(zone, utcoffset=None, dstoffset=None, tzname=None):
"""Factory function for unpickling pytz tzinfo instances.