Skip to content

Commit

Permalink
utils: iso8601: strip fractional seconds
Browse files Browse the repository at this point in the history
According to ISO8601 any number of digits is permitted for fractional
seconds, the issue is that Python assumes these are microsecond, and
will fail if we have more than 6 digits.

In the event that we detect more that 6 digits, truncate the fractional
part and pass it to datetime.

Signed-off-by: Liam Beguin <liambeguin@gmail.com>
  • Loading branch information
liambeguin committed Apr 8, 2024
1 parent c5d194d commit 3caf471
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
7 changes: 7 additions & 0 deletions sigmf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from datetime import datetime
import sys
import numpy as np
import re

from . import error

Expand All @@ -30,6 +31,12 @@ def parse_iso8601_datetime(datestr: str) -> datetime:
>>> parse_iso8601_datetime("1955-11-05T06:15:00Z")
datetime.datetime(1955, 11, 5, 6, 15)
"""
m = re.match(r'^(?P<dt>.*)(?P<frac>\.[0-9]{7,})Z$', datestr)
if m:
d = m.groupdict()
l = min(7, len(d['frac']))
datestr = ''.join([d['dt'], d['frac'][:l], 'Z'])

try:
timestamp = datetime.strptime(datestr, '%Y-%m-%dT%H:%M:%S.%fZ')
except ValueError:
Expand Down
17 changes: 17 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import datetime

import pytest

from sigmf import utils

@pytest.mark.parametrize('ts,expected', [
('1955-08-05T06:15:00Z', datetime.datetime(year=1955, month=8 , day=5, hour=6 , minute=15, second=00, microsecond=0)),
('1956-09-06T07:15:12Z', datetime.datetime(year=1956, month=9 , day=6, hour=7 , minute=15, second=12, microsecond=0)),
('1957-10-07T08:15:12.345Z', datetime.datetime(year=1957, month=10, day=7, hour=8 , minute=15, second=12, microsecond=345000)),
('1958-11-08T09:15:12.0345Z', datetime.datetime(year=1958, month=11, day=8, hour=9 , minute=15, second=12, microsecond=34500)),
('1959-12-09T10:15:12.000000Z', datetime.datetime(year=1959, month=12, day=9, hour=10, minute=15, second=12, microsecond=0)),
('1959-12-09T10:15:12.123456789123Z', datetime.datetime(year=1959, month=12, day=9, hour=10, minute=15, second=12, microsecond=123456)),
])
def test_parse_simple_iso8601(ts, expected):
dt = utils.parse_iso8601_datetime(ts)
assert dt == expected

0 comments on commit 3caf471

Please sign in to comment.