Skip to content

Commit

Permalink
Use 'DatetimeWithNanos' for converting timestamp messages. (#6920)
Browse files Browse the repository at this point in the history
  • Loading branch information
tseaver authored Dec 17, 2018
1 parent 54e87e1 commit 274c3a2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
10 changes: 5 additions & 5 deletions firestore/google/cloud/firestore_v1beta1/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from google.cloud import exceptions
from google.cloud._helpers import _datetime_to_pb_timestamp
from google.cloud._helpers import _pb_timestamp_to_datetime
from google.api_core.datetime_helpers import DatetimeWithNanoseconds
from google.cloud.firestore_v1beta1 import transforms
from google.cloud.firestore_v1beta1 import types
from google.cloud.firestore_v1beta1.field_path import FieldPath
Expand Down Expand Up @@ -165,6 +165,9 @@ def encode_value(value):
if isinstance(value, float):
return document_pb2.Value(double_value=value)

if isinstance(value, DatetimeWithNanoseconds):
return document_pb2.Value(timestamp_value=value.timestamp_pb())

if isinstance(value, datetime.datetime):
return document_pb2.Value(timestamp_value=_datetime_to_pb_timestamp(value))

Expand Down Expand Up @@ -275,10 +278,7 @@ def decode_value(value, client):
elif value_type == "double_value":
return value.double_value
elif value_type == "timestamp_value":
# NOTE: This conversion is "lossy", Python ``datetime.datetime``
# has microsecond precision but ``timestamp_value`` has
# nanosecond precision.
return _pb_timestamp_to_datetime(value.timestamp_value)
return DatetimeWithNanoseconds.from_timestamp_pb(value.timestamp_value)
elif value_type == "string_value":
return value.string_value
elif value_type == "bytes_value":
Expand Down
25 changes: 17 additions & 8 deletions firestore/tests/unit/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,20 @@ def test_float(self):
expected = _value_pb(double_value=value)
self.assertEqual(result, expected)

def test_datetime(self):
def test_datetime_with_nanos(self):
from google.api_core.datetime_helpers import DatetimeWithNanoseconds
from google.protobuf import timestamp_pb2

dt_seconds = 1488768504
dt_nanos = 458816991
timestamp_pb = timestamp_pb2.Timestamp(seconds=dt_seconds, nanos=dt_nanos)
dt_val = DatetimeWithNanoseconds.from_timestamp_pb(timestamp_pb)

result = self._call_fut(dt_val)
expected = _value_pb(timestamp_value=timestamp_pb)
self.assertEqual(result, expected)

def test_datetime_wo_nanos(self):
from google.protobuf import timestamp_pb2

dt_seconds = 1488768504
Expand Down Expand Up @@ -387,20 +400,16 @@ def test_float(self):
(3,) <= sys.version_info < (3, 4, 4), "known datetime bug (bpo-23517) in Python"
)
def test_datetime(self):
from google.api_core.datetime_helpers import DatetimeWithNanoseconds
from google.protobuf import timestamp_pb2
from google.cloud._helpers import UTC

dt_seconds = 552855006
dt_nanos = 766961000
# Make sure precision is valid in microseconds too.
self.assertEqual(dt_nanos % 1000, 0)
dt_nanos = 766961828

timestamp_pb = timestamp_pb2.Timestamp(seconds=dt_seconds, nanos=dt_nanos)
value = _value_pb(timestamp_value=timestamp_pb)

expected_dt_val = datetime.datetime.utcfromtimestamp(
dt_seconds + 1e-9 * dt_nanos
).replace(tzinfo=UTC)
expected_dt_val = DatetimeWithNanoseconds.from_timestamp_pb(timestamp_pb)
self.assertEqual(self._call_fut(value), expected_dt_val)

def test_unicode(self):
Expand Down

0 comments on commit 274c3a2

Please sign in to comment.