Skip to content

Commit

Permalink
Merge pull request #1785 from tseaver/1783-timestamp_nanos_truncated
Browse files Browse the repository at this point in the history
Tolerate timestamps w/ truncated nanos.
  • Loading branch information
tseaver committed May 12, 2016
2 parents 096b5f6 + d1edca0 commit cd8e645
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 10 deletions.
6 changes: 4 additions & 2 deletions gcloud/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2} # YYYY-MM-DDTHH:MM:SS
)
\. # decimal point
(?P<nanos>\d{9}) # nanoseconds
(?P<nanos>\d{1,9}) # nanoseconds, maybe truncated
Z # Zulu
""", re.VERBOSE)

Expand Down Expand Up @@ -344,7 +344,9 @@ def _rfc3339_nanos_to_datetime(dt_str):
dt_str, _RFC3339_NANOS.pattern))
bare_seconds = datetime.datetime.strptime(
with_nanos.group('no_fraction'), _RFC3339_NO_FRACTION)
nanos = int(with_nanos.group('nanos'))
fraction = with_nanos.group('nanos')
scale = 9 - len(fraction)
nanos = int(fraction) * (10 ** scale)
micros = nanos // 1000
return bare_seconds.replace(microsecond=micros, tzinfo=UTC)

Expand Down
30 changes: 22 additions & 8 deletions gcloud/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,20 +483,34 @@ def test_w_bogus_zone(self):
with self.assertRaises(ValueError):
self._callFUT(dt_str)

def test_w_microseconds(self):
def test_w_truncated_nanos(self):
import datetime
from gcloud._helpers import UTC

year = 2009
month = 12
day = 17
hour = 12
minute = 44
seconds = 32
micros = 123456

dt_str = '%d-%02d-%02dT%02d:%02d:%02d.%06dZ' % (
year, month, day, hour, minute, seconds, micros)
with self.assertRaises(ValueError):
self._callFUT(dt_str)
truncateds_and_micros = [
('12345678', 123456),
('1234567', 123456),
('123456', 123456),
('12345', 123450),
('1234', 123400),
('123', 123000),
('12', 120000),
('1', 100000),
]

for truncated, micros in truncateds_and_micros:
dt_str = '%d-%02d-%02dT%02d:%02d:%02d.%sZ' % (
year, month, day, hour, minute, seconds, truncated)
result = self._callFUT(dt_str)
expected_result = datetime.datetime(
year, month, day, hour, minute, seconds, micros, UTC)
self.assertEqual(result, expected_result)

def test_w_naonseconds(self):
import datetime
Expand All @@ -511,7 +525,7 @@ def test_w_naonseconds(self):
nanos = 123456789
micros = nanos // 1000

dt_str = '%d-%02d-%02dT%02d:%02d:%02d.%06dZ' % (
dt_str = '%d-%02d-%02dT%02d:%02d:%02d.%09dZ' % (
year, month, day, hour, minute, seconds, nanos)
result = self._callFUT(dt_str)
expected_result = datetime.datetime(
Expand Down

0 comments on commit cd8e645

Please sign in to comment.