summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Krotscheck <krotscheck@gmail.com>2015-03-03 14:36:15 -0800
committerMichael Krotscheck <krotscheck@gmail.com>2015-05-22 09:36:39 -0700
commit3ea152cab0933c6d1d3a7eced33c8122f4c917ec (patch)
tree3f759a805ea0773218e34fdddd0005cd477d63c8
parentf28ec1354e2ef1a92cd7eaf5e7c363e2107280ce (diff)
downloadwsme-3ea152cab0933c6d1d3a7eced33c8122f4c917ec.tar.gz
Added timezone support to parse_isodatetime
Timezones are added to datetime() and time() instances using pytz's FixedOffset. Change-Id: I2484c5cd924348305e681dc2902bafd19c75eb6e
-rw-r--r--wsme/tests/test_utils.py25
-rw-r--r--wsme/utils.py24
2 files changed, 42 insertions, 7 deletions
diff --git a/wsme/tests/test_utils.py b/wsme/tests/test_utils.py
index 81b8296..a6165dd 100644
--- a/wsme/tests/test_utils.py
+++ b/wsme/tests/test_utils.py
@@ -1,5 +1,6 @@
import datetime
import unittest
+import pytz
from wsme import utils
@@ -26,6 +27,11 @@ class TestUtils(unittest.TestCase):
good_times = [
('12:03:54', datetime.time(12, 3, 54)),
('23:59:59.000004', datetime.time(23, 59, 59, 4)),
+ ('01:02:03+00:00', datetime.time(1, 2, 3, 0, pytz.UTC)),
+ ('01:02:03+23:59', datetime.time(1, 2, 3, 0,
+ pytz.FixedOffset(1439))),
+ ('01:02:03-23:59', datetime.time(1, 2, 3, 0,
+ pytz.FixedOffset(-1439))),
]
ill_formatted_times = [
'24-12-2004'
@@ -33,6 +39,8 @@ class TestUtils(unittest.TestCase):
out_of_range_times = [
'32:12:00',
'00:54:60',
+ '01:02:03-24:00',
+ '01:02:03+24:00',
]
for s, t in good_times:
assert utils.parse_isotime(s) == t
@@ -42,16 +50,27 @@ class TestUtils(unittest.TestCase):
def test_parse_isodatetime(self):
good_datetimes = [
('2008-02-12T12:03:54',
- datetime.datetime(2008, 2, 12, 12, 3, 54)),
+ datetime.datetime(2008, 2, 12, 12, 3, 54)),
('2012-05-14T23:59:59.000004',
- datetime.datetime(2012, 5, 14, 23, 59, 59, 4)),
+ datetime.datetime(2012, 5, 14, 23, 59, 59, 4)),
+ ('1856-07-10T01:02:03+00:00',
+ datetime.datetime(1856, 7, 10, 1, 2, 3, 0, pytz.UTC)),
+ ('1856-07-10T01:02:03+23:59',
+ datetime.datetime(1856, 7, 10, 1, 2, 3, 0,
+ pytz.FixedOffset(1439))),
+ ('1856-07-10T01:02:03-23:59',
+ datetime.datetime(1856, 7, 10, 1, 2, 3, 0,
+ pytz.FixedOffset(-1439))),
]
ill_formatted_datetimes = [
- '24-12-2004'
+ '24-12-2004',
+ '1856-07-10+33:00'
]
out_of_range_datetimes = [
'2008-02-12T32:12:00',
'2012-13-12T00:54:60',
+ '1856-07-10T01:02:03-24:00',
+ '1856-07-10T01:02:03+24:00',
]
for s, t in good_datetimes:
assert utils.parse_isodatetime(s) == t
diff --git a/wsme/utils.py b/wsme/utils.py
index d7f3486..e0c65dc 100644
--- a/wsme/utils.py
+++ b/wsme/utils.py
@@ -1,5 +1,6 @@
import decimal
import datetime
+import pytz
import re
from six.moves import builtins, http_client
@@ -17,7 +18,7 @@ tz_re = r'((?P<tz_sign>[+-])(?P<tz_hour>\d{2}):(?P<tz_min>\d{2}))' + \
datetime_re = re.compile(
'%sT%s(%s)?' % (date_re, time_re, tz_re))
date_re = re.compile(date_re)
-time_re = re.compile(time_re)
+time_re = re.compile('%s(%s)?' % (time_re, tz_re))
if hasattr(builtins, '_'):
@@ -50,16 +51,17 @@ def parse_isotime(value):
f = decimal.Decimal('0.' + m.group('sec_frac'))
f = str(f.quantize(decimal.Decimal('0.000001')))
ms = int(f[2:])
+ tz = _parse_tzparts(m.groupdict())
return datetime.time(
int(m.group('hour')),
int(m.group('min')),
int(m.group('sec')),
- ms)
+ ms,
+ tz)
except ValueError:
raise ValueError("'%s' is a out-of-range time" % (value))
-# TODO handle timezone
def parse_isodatetime(value):
if dateutil:
return dateutil.parser.parse(value)
@@ -72,6 +74,7 @@ def parse_isodatetime(value):
f = decimal.Decimal('0.' + m.group('sec_frac'))
f = f.quantize(decimal.Decimal('0.000001'))
ms = int(str(f)[2:])
+ tz = _parse_tzparts(m.groupdict())
return datetime.datetime(
int(m.group('year')),
int(m.group('month')),
@@ -79,11 +82,24 @@ def parse_isodatetime(value):
int(m.group('hour')),
int(m.group('min')),
int(m.group('sec')),
- ms)
+ ms,
+ tz)
except ValueError:
raise ValueError("'%s' is a out-of-range datetime" % (value))
+def _parse_tzparts(parts):
+ if 'tz_z' in parts and parts['tz_z'] == 'Z':
+ return pytz.UTC
+ if 'tz_min' not in parts or not parts['tz_min']:
+ return None
+
+ tz_minute_offset = (int(parts['tz_hour']) * 60 + int(parts['tz_min']))
+ tz_multiplier = -1 if parts['tz_sign'] == '-' else 1
+
+ return pytz.FixedOffset(tz_multiplier * tz_minute_offset)
+
+
def is_valid_code(code_value):
"""
This function checks if incoming value in http response codes range.