aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Ganssle <pganssle@users.noreply.github.com>2018-03-14 19:10:41 -0400
committerGitHub <noreply@github.com>2018-03-14 19:10:41 -0400
commita09c9d65bd4a5fbc344593905bf81e175e3539c0 (patch)
tree3ab898d7188dfc7677ed70e4658d3d8b04b40142
parent231c7e3b2031889ae246743d41beddb6506473f8 (diff)
parentefba12d340e0c5aa94f881581d693c259cd24bcf (diff)
downloaddateutil-a09c9d65bd4a5fbc344593905bf81e175e3539c0.tar.gz
Merge pull request #634 from ryanpetrello/fix-633
require UTC for UNTIL when DTSTART is timezone-aware
-rw-r--r--dateutil/rrule.py15
-rw-r--r--dateutil/test/test_rrule.py14
2 files changed, 29 insertions, 0 deletions
diff --git a/dateutil/rrule.py b/dateutil/rrule.py
index 6d6adb1..ef4607a 100644
--- a/dateutil/rrule.py
+++ b/dateutil/rrule.py
@@ -21,6 +21,7 @@ from six.moves import _thread, range
import heapq
from ._common import weekday as weekdaybase
+from .tz import tzutc, tzlocal
# For warning about deprecation of until and count
from warnings import warn
@@ -447,6 +448,20 @@ class rrule(rrulebase):
until = datetime.datetime.fromordinal(until.toordinal())
self._until = until
+ if self._dtstart and self._until:
+ if (self._dtstart.tzinfo is not None) != (self._until.tzinfo is not None):
+ # According to RFC5545 Section 3.3.10:
+ # https://tools.ietf.org/html/rfc5545#section-3.3.10
+ #
+ # > If the "DTSTART" property is specified as a date with UTC
+ # > time or a date with local time and time zone reference,
+ # > then the UNTIL rule part MUST be specified as a date with
+ # > UTC time.
+ raise ValueError(
+ 'RRULE UNTIL values must be specified in UTC when DTSTART '
+ 'is timezone-aware'
+ )
+
if count is not None and until:
warn("Using both 'count' and 'until' is inconsistent with RFC 5545"
" and has been deprecated in dateutil. Future versions will "
diff --git a/dateutil/test/test_rrule.py b/dateutil/test/test_rrule.py
index 57ec9b3..9ac948d 100644
--- a/dateutil/test/test_rrule.py
+++ b/dateutil/test/test_rrule.py
@@ -2930,6 +2930,20 @@ class RRuleTest(WarningTestMixin, unittest.TestCase):
"RRULE:FREQ=YEARLY;"
"UNTIL=TheCowsComeHome;BYDAY=1TU,-1TH\n"))
+ def testStrUntilMustBeUTC(self):
+ with self.assertRaises(ValueError):
+ list(rrulestr("DTSTART;TZID=America/New_York:19970902T090000\n"
+ "RRULE:FREQ=YEARLY;"
+ "UNTIL=19990101T000000;BYDAY=1TU,-1TH\n"))
+
+ def testStrUntilWithTZ(self):
+ NYC = tz.gettz('America/New_York')
+ rr = list(rrulestr("DTSTART;TZID=America/New_York:19970101T000000\n"
+ "RRULE:FREQ=YEARLY;"
+ "UNTIL=19990101T000000Z\n"))
+ self.assertEqual(list(rr), [datetime(1997, 1, 1, 0, 0, 0, tzinfo=NYC),
+ datetime(1998, 1, 1, 0, 0, 0, tzinfo=NYC)])
+
def testStrEmptyByDay(self):
with self.assertRaises(ValueError):
list(rrulestr("DTSTART:19970902T090000\n"