summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Twomey <michael.twomey@fieldaware.com>2013-10-18 17:39:16 +0100
committerMichael Twomey <michael.twomey@fieldaware.com>2013-10-18 17:39:16 +0100
commit292b24a47d8e417a81bc105eec0dcd89dda1f716 (patch)
tree069081be6396236e63a3c7f36547ae6472bdac2e
parentc7f06717462f20ee7829f42f1ea41a8becac3edc (diff)
downloadpyiso8601-292b24a47d8e417a81bc105eec0dcd89dda1f716.tar.gz
Handle negative timezone offsets correctly0.1.6
I had dropped the negative minutes in a braino and had incorrectly updated tests to match. I've added a isoformat field to the tests, so I can correctly assert they formatted date looks right. Thanks to Jonathan Lange for reporting this and a patch. Fixes #8
-rw-r--r--README.rst5
-rw-r--r--iso8601/iso8601.py1
-rw-r--r--iso8601/test_iso8601.py51
3 files changed, 34 insertions, 23 deletions
diff --git a/README.rst b/README.rst
index 02ce06a..e3ab871 100644
--- a/README.rst
+++ b/README.rst
@@ -102,6 +102,11 @@ Python 2.5 is not supported (too old for the tests for the most part). It could
Changes
=======
+0.1.6
+-----
+
+* Correct negative timezone offsets (https://bitbucket.org/micktwomey/pyiso8601/issue/8/015-parses-negative-timezones-incorrectly) (thanks to Jonathan Lange)
+
0.1.5
-----
diff --git a/iso8601/iso8601.py b/iso8601/iso8601.py
index efd6413..31015bd 100644
--- a/iso8601/iso8601.py
+++ b/iso8601/iso8601.py
@@ -146,6 +146,7 @@ def parse_timezone(matches, default_timezone=UTC):
description = "%s%02d:%02d" % (sign, hours, minutes)
if sign == "-":
hours = -hours
+ minutes = -minutes
return FixedOffset(hours, minutes, description)
def parse_date(datestring, default_timezone=UTC):
diff --git a/iso8601/test_iso8601.py b/iso8601/test_iso8601.py
index 30d6a1d..5ec4e69 100644
--- a/iso8601/test_iso8601.py
+++ b/iso8601/test_iso8601.py
@@ -42,30 +42,33 @@ def test_parse_invalid_date(invalid_date):
iso8601.parse_date(invalid_date)
assert exc.errisinstance(iso8601.ParseError)
-@pytest.mark.parametrize("valid_date,expected_datetime", [
- ("2007-06-23 06:40:34.00Z", datetime.datetime(2007, 6, 23, 6, 40, 34, 0, iso8601.UTC)), # Handle a separator other than T
- ("1997-07-16T19:20+01:00", datetime.datetime(1997, 7, 16, 19, 20, 0, 0, iso8601.FixedOffset(1, 0, "+01:00"))), # Parse with no seconds
- ("2007-01-01T08:00:00", datetime.datetime(2007, 1, 1, 8, 0, 0, 0, iso8601.UTC)), # Handle timezone-less dates. Assumes UTC. http://code.google.com/p/pyiso8601/issues/detail?id=4
- ("2006-10-20T15:34:56.123+02:30", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.FixedOffset(2, 30, "+02:30"))),
- ("2006-10-20T15:34:56Z", datetime.datetime(2006, 10, 20, 15, 34, 56, 0, iso8601.UTC)),
- ("2007-5-7T11:43:55.328Z'", datetime.datetime(2007, 5, 7, 11, 43, 55, 328000, iso8601.UTC)), # http://code.google.com/p/pyiso8601/issues/detail?id=6
- ("2006-10-20T15:34:56.123Z", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.UTC)),
- ("2013-10-15T18:30Z", datetime.datetime(2013, 10, 15, 18, 30, 0, 0, iso8601.UTC)),
- ("2013-10-15T22:30+04", datetime.datetime(2013, 10, 15, 22, 30, 0, 0, iso8601.FixedOffset(4, 0, "+04:00"))), # <time>±hh:mm
- ("2013-10-15T1130-0700", datetime.datetime(2013, 10, 15, 11, 30, 0, 0, iso8601.FixedOffset(-7, 0, "-07:00"))), # <time>±hhmm
- ("2013-10-15T1130+0700", datetime.datetime(2013, 10, 15, 11, 30, 0, 0, iso8601.FixedOffset(+7, 0, "+07:00"))), # <time>±hhmm
- ("2013-10-15T15:00-03:30", datetime.datetime(2013, 10, 15, 15, 0, 0, 0, iso8601.FixedOffset(-3, 30, "-03:30"))), # <time>±hh
- ("2013-10-15T183123Z", datetime.datetime(2013, 10, 15, 18, 31, 23, 0, iso8601.UTC)), # hhmmss
- ("2013-10-15T1831Z", datetime.datetime(2013, 10, 15, 18, 31, 0, 0, iso8601.UTC)), # hhmm
- ("2013-10-15T18Z", datetime.datetime(2013, 10, 15, 18, 0, 0, 0, iso8601.UTC)), # hh
- ("20131015T18:30Z", datetime.datetime(2013, 10, 15, 18, 30, 0, 0, iso8601.UTC)), # YYYYMMDD
- ("2012-12-19T23:21:28.512400+00:00", datetime.datetime(2012, 12, 19, 23, 21, 28, 512400, iso8601.FixedOffset(0, 0, "+00:00"))), # https://code.google.com/p/pyiso8601/issues/detail?id=21
- ("2006-10-20T15:34:56.123+0230", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.FixedOffset(2, 30, "+02:30"))), # https://code.google.com/p/pyiso8601/issues/detail?id=18
- ("19950204", datetime.datetime(1995, 2, 4, tzinfo=iso8601.UTC)), # https://code.google.com/p/pyiso8601/issues/detail?id=1
- ("2010-07-20 15:25:52.520701+00:00", datetime.datetime(2010, 7, 20, 15, 25, 52, 520701, iso8601.FixedOffset(0, 0, "+00:00"))), # https://code.google.com/p/pyiso8601/issues/detail?id=17
- ("2010-06-12", datetime.datetime(2010, 6, 12, tzinfo=iso8601.UTC)), # https://code.google.com/p/pyiso8601/issues/detail?id=16
+@pytest.mark.parametrize("valid_date,expected_datetime,isoformat", [
+ ("2007-06-23 06:40:34.00Z", datetime.datetime(2007, 6, 23, 6, 40, 34, 0, iso8601.UTC), None), # Handle a separator other than T
+ ("1997-07-16T19:20+01:00", datetime.datetime(1997, 7, 16, 19, 20, 0, 0, iso8601.FixedOffset(1, 0, "+01:00")), None), # Parse with no seconds
+ ("2007-01-01T08:00:00", datetime.datetime(2007, 1, 1, 8, 0, 0, 0, iso8601.UTC), None), # Handle timezone-less dates. Assumes UTC. http://code.google.com/p/pyiso8601/issues/detail?id=4
+ ("2006-10-20T15:34:56.123+02:30", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.FixedOffset(2, 30, "+02:30")), None),
+ ("2006-10-20T15:34:56Z", datetime.datetime(2006, 10, 20, 15, 34, 56, 0, iso8601.UTC), None),
+ ("2007-5-7T11:43:55.328Z'", datetime.datetime(2007, 5, 7, 11, 43, 55, 328000, iso8601.UTC), None), # http://code.google.com/p/pyiso8601/issues/detail?id=6
+ ("2006-10-20T15:34:56.123Z", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.UTC), None),
+ ("2013-10-15T18:30Z", datetime.datetime(2013, 10, 15, 18, 30, 0, 0, iso8601.UTC), None),
+ ("2013-10-15T22:30+04", datetime.datetime(2013, 10, 15, 22, 30, 0, 0, iso8601.FixedOffset(4, 0, "+04:00")), None), # <time>±hh:mm
+ ("2013-10-15T1130-0700", datetime.datetime(2013, 10, 15, 11, 30, 0, 0, iso8601.FixedOffset(-7, 0, "-07:00")), None), # <time>±hhmm
+ ("2013-10-15T1130+0700", datetime.datetime(2013, 10, 15, 11, 30, 0, 0, iso8601.FixedOffset(+7, 0, "+07:00")), None), # <time>±hhmm
+ ("2013-10-15T1130+07", datetime.datetime(2013, 10, 15, 11, 30, 0, 0, iso8601.FixedOffset(+7, 0, "+07:00")), None), # <time>±hh
+ ("2013-10-15T1130-07", datetime.datetime(2013, 10, 15, 11, 30, 0, 0, iso8601.FixedOffset(-7, 0, "-07:00")), None), # <time>±hh
+ ("2013-10-15T15:00-03:30", datetime.datetime(2013, 10, 15, 15, 0, 0, 0, iso8601.FixedOffset(-3, -30, "-03:30")), "2013-10-15T15:00:00-03:30"),
+ ("2013-10-15T183123Z", datetime.datetime(2013, 10, 15, 18, 31, 23, 0, iso8601.UTC), None), # hhmmss
+ ("2013-10-15T1831Z", datetime.datetime(2013, 10, 15, 18, 31, 0, 0, iso8601.UTC), None), # hhmm
+ ("2013-10-15T18Z", datetime.datetime(2013, 10, 15, 18, 0, 0, 0, iso8601.UTC), None), # hh
+ ("20131015T18:30Z", datetime.datetime(2013, 10, 15, 18, 30, 0, 0, iso8601.UTC), None), # YYYYMMDD
+ ("2012-12-19T23:21:28.512400+00:00", datetime.datetime(2012, 12, 19, 23, 21, 28, 512400, iso8601.FixedOffset(0, 0, "+00:00")), None), # https://code.google.com/p/pyiso8601/issues/detail?id=21
+ ("2006-10-20T15:34:56.123+0230", datetime.datetime(2006, 10, 20, 15, 34, 56, 123000, iso8601.FixedOffset(2, 30, "+02:30")), None), # https://code.google.com/p/pyiso8601/issues/detail?id=18
+ ("19950204", datetime.datetime(1995, 2, 4, tzinfo=iso8601.UTC), None), # https://code.google.com/p/pyiso8601/issues/detail?id=1
+ ("2010-07-20 15:25:52.520701+00:00", datetime.datetime(2010, 7, 20, 15, 25, 52, 520701, iso8601.FixedOffset(0, 0, "+00:00")), None), # https://code.google.com/p/pyiso8601/issues/detail?id=17
+ ("2010-06-12", datetime.datetime(2010, 6, 12, tzinfo=iso8601.UTC), None), # https://code.google.com/p/pyiso8601/issues/detail?id=16
+ ("1985-04-12T23:20:50.52-05:30", datetime.datetime(1985, 4, 12, 23, 20, 50, 520000, iso8601.FixedOffset(-5, -30, "-05:30")), "1985-04-12T23:20:50.520000-05:30"), # https://bitbucket.org/micktwomey/pyiso8601/issue/8/015-parses-negative-timezones-incorrectly
])
-def test_parse_valid_date(valid_date, expected_datetime):
+def test_parse_valid_date(valid_date, expected_datetime, isoformat):
parsed = iso8601.parse_date(valid_date)
assert parsed.year == expected_datetime.year
assert parsed.month == expected_datetime.month
@@ -79,3 +82,5 @@ def test_parse_valid_date(valid_date, expected_datetime):
assert parsed.isoformat() == expected_datetime.isoformat()
copy.deepcopy(parsed) # ensure it's deep copy-able
pickle.dumps(parsed) # ensure it pickles
+ if isoformat:
+ assert parsed.isoformat() == isoformat