summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@gmail.com>2015-02-10 08:19:20 -0800
committerJoshua Harlow <harlowja@gmail.com>2015-02-11 20:55:51 -0800
commit9f2a2edb56e67e592f52122e54deecef17f2d922 (patch)
tree9c598f1b20645e55a3576bc80b194ced818d5de6
parentc395de920b8bf2313fe245ec116710001a8fd7d9 (diff)
downloadoslo-serialization-9f2a2edb56e67e592f52122e54deecef17f2d922.tar.gz
Avoid using strtime for serializing datetimes
The timeutils module already provides a better marshall/unmarshall routine that doesn't use strtime but uses dictionary conversion instead so we should just use that (to avoid the weirdness with strtime). Change-Id: Ia7c88ec4266f914d0c89b67a3fb2b936cc1a1c93
-rw-r--r--oslo_serialization/msgpackutils.py31
-rw-r--r--requirements.txt1
-rw-r--r--tests/test_msgpackutils.py34
3 files changed, 59 insertions, 7 deletions
diff --git a/oslo_serialization/msgpackutils.py b/oslo_serialization/msgpackutils.py
index 570e3a5..ac4f703 100644
--- a/oslo_serialization/msgpackutils.py
+++ b/oslo_serialization/msgpackutils.py
@@ -19,7 +19,7 @@ import uuid
import msgpack
from oslo_utils import importutils
-from oslo_utils import timeutils
+from pytz import timezone
import six
import six.moves.xmlrpc_client as xmlrpclib
@@ -34,14 +34,33 @@ else:
def _serialize_datetime(dt):
- blob = timeutils.strtime(dt)
- if six.PY3:
- return blob.encode('ascii')
- return blob
+ dct = {
+ 'day': dt.day,
+ 'month': dt.month,
+ 'year': dt.year,
+ 'hour': dt.hour,
+ 'minute': dt.minute,
+ 'second': dt.second,
+ 'microsecond': dt.microsecond,
+ }
+ if dt.tzinfo:
+ dct['tz'] = dt.tzinfo.tzname(None)
+ return dumps(dct)
def _deserialize_datetime(blob):
- return timeutils.parse_strtime(six.text_type(blob, encoding='ascii'))
+ dct = loads(blob)
+ dt = datetime.datetime(day=dct['day'],
+ month=dct['month'],
+ year=dct['year'],
+ hour=dct['hour'],
+ minute=dct['minute'],
+ second=dct['second'],
+ microsecond=dct['microsecond'])
+ if 'tz' in dct:
+ tzinfo = timezone(dct['tz'])
+ dt = tzinfo.localize(dt)
+ return dt
def _serializer(obj):
diff --git a/requirements.txt b/requirements.txt
index eb6cf00..74ef925 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,3 +10,4 @@ msgpack-python>=0.4.0
# library version this can be removed.
iso8601>=0.1.9
oslo.utils>=1.2.0 # Apache-2.0
+pytz>=2013.6
diff --git a/tests/test_msgpackutils.py b/tests/test_msgpackutils.py
index 00c6c6b..8a9f965 100644
--- a/tests/test_msgpackutils.py
+++ b/tests/test_msgpackutils.py
@@ -19,6 +19,7 @@ import uuid
import netaddr
from oslotest import base as test_base
+from pytz import timezone
import six
import six.moves.xmlrpc_client as xmlrpclib
import testtools
@@ -33,6 +34,9 @@ else:
_PY26 = False
+_TZ_FMT = '%Y-%m-%d %H:%M:%S %Z%z'
+
+
def _dumps_loads(obj):
obj = msgpackutils.dumps(obj)
return msgpackutils.loads(obj)
@@ -107,7 +111,7 @@ class MsgPackUtilsTestMixin(test_base.BaseTestCase):
x = datetime.datetime(1920, 2, 3, 4, 5, 6, 7)
self.assertEqual(_dumps_loads(x), x)
- def test_DateTime(self):
+ def test_datetime(self):
x = xmlrpclib.DateTime()
x.decode("19710203T04:05:06")
self.assertEqual(_dumps_loads(x), x)
@@ -115,3 +119,31 @@ class MsgPackUtilsTestMixin(test_base.BaseTestCase):
def test_ipaddr(self):
thing = {'ip_addr': netaddr.IPAddress('1.2.3.4')}
self.assertEqual(_dumps_loads(thing), thing)
+
+ def test_datetime_tz_clone(self):
+ eastern = timezone('US/Eastern')
+ now = datetime.datetime.now()
+ e_dt = eastern.localize(now)
+ e_dt2 = _dumps_loads(e_dt)
+ self.assertEqual(e_dt, e_dt2)
+ self.assertEqual(e_dt.strftime(_TZ_FMT), e_dt2.strftime(_TZ_FMT))
+
+ def test_datetime_tz_different(self):
+ eastern = timezone('US/Eastern')
+ pacific = timezone('US/Pacific')
+ now = datetime.datetime.now()
+
+ e_dt = eastern.localize(now)
+ p_dt = pacific.localize(now)
+
+ self.assertNotEqual(e_dt, p_dt)
+ self.assertNotEqual(e_dt.strftime(_TZ_FMT), p_dt.strftime(_TZ_FMT))
+
+ e_dt2 = _dumps_loads(e_dt)
+ p_dt2 = _dumps_loads(p_dt)
+
+ self.assertNotEqual(e_dt2, p_dt2)
+ self.assertNotEqual(e_dt2.strftime(_TZ_FMT), p_dt2.strftime(_TZ_FMT))
+
+ self.assertEqual(e_dt, e_dt2)
+ self.assertEqual(p_dt, p_dt2)