Browse Source

fix to properly use UTC for datetimes.

The other test changes were needed because:
datetime[.]now() != b.astimezone(timezone.utc)

because of course the python datetime library is bad...
main
John-Mark Gurney 2 years ago
parent
commit
d940de70ea
1 changed files with 30 additions and 5 deletions
  1. +30
    -5
      pasn1.py

+ 30
- 5
pasn1.py View File

@@ -364,6 +364,7 @@ class ASN1Coder(object):
return fun(data, pos + 1 + b, end) return fun(data, pos + 1 + b, end)


def enc_datetime(self, obj, **kwargs): def enc_datetime(self, obj, **kwargs):
obj = obj.astimezone(datetime.timezone.utc)
ts = obj.strftime('%Y%m%d%H%M%S') ts = obj.strftime('%Y%m%d%H%M%S')
if obj.microsecond: if obj.microsecond:
ts += ('.%06d' % obj.microsecond).rstrip('0') ts += ('.%06d' % obj.microsecond).rstrip('0')
@@ -385,7 +386,7 @@ class ASN1Coder(object):
raise ValueError('invalid trailing zeros') raise ValueError('invalid trailing zeros')
else: else:
fstr = '%Y%m%d%H%M%SZ' fstr = '%Y%m%d%H%M%SZ'
return datetime.datetime.strptime(ts, fstr), end
return datetime.datetime.strptime(ts, fstr).replace(tzinfo=datetime.timezone.utc), end


def loads(self, data, pos=0, end=None, consume=False): def loads(self, data, pos=0, end=None, consume=False):
'''Load from data, starting at pos (optional), and ending '''Load from data, starting at pos (optional), and ending
@@ -602,6 +603,30 @@ class TestCode(unittest.TestCase):
# XXX - add test to reject datetime w/ tzinfo, or that it # XXX - add test to reject datetime w/ tzinfo, or that it
# handles it properly # handles it properly


def test_tzdate(self):
dlocal = datetime.datetime.now()
dutc = dlocal.astimezone(datetime.timezone.utc)
dts = dutc.timestamp()

# sanity check
self.assertEqual(dts, dlocal.timestamp())

# verify that the same datetime, but with different
# tzinfo, is serialized the same way
self.assertEqual(dumps(dlocal), dumps(dutc))

# that when dutc is read back
dround = loads(dumps(dutc))

# that it represents the same time
self.assertEqual(dround.timestamp(), dts)

# that when dlocal is read back
dround = loads(dumps(dlocal))

# that it represents the same time
self.assertEqual(dround.timestamp(), dts)

def test_dumps(self): def test_dumps(self):
for i in [ None, for i in [ None,
True, False, True, False,
@@ -619,10 +644,10 @@ class TestCode(unittest.TestCase):
{}, { 5: 10, 'adfkj': 34 }, {}, { 5: 10, 'adfkj': 34 },
set(), set((1,2,3)), set(), set((1,2,3)),
set((1,'sjlfdkj', None, float('inf'))), set((1,'sjlfdkj', None, float('inf'))),
datetime.datetime.utcnow(),
[ datetime.datetime.utcnow(), ' ' ],
datetime.datetime.utcnow().replace(microsecond=0),
datetime.datetime.utcnow().replace(microsecond=1000),
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc),
[ datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc), ' ' ],
datetime.datetime.utcnow().replace(microsecond=0, tzinfo=datetime.timezone.utc),
datetime.datetime.utcnow().replace(microsecond=1000, tzinfo=datetime.timezone.utc),
]: ]:
s = dumps(i) s = dumps(i)
o = loads(s) o = loads(s)


Loading…
Cancel
Save