Skip to content

Commit

Permalink
Merge pull request #55 from jgeewax/datetime-fix-again
Browse files Browse the repository at this point in the history
Fixed #50 - timestamps need to be int/long, not float.
  • Loading branch information
jgeewax committed Mar 8, 2014
2 parents 2c26d9b + 8a0b8cd commit bc0c1fd
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
17 changes: 13 additions & 4 deletions gcloud/datastore/helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Helper methods for dealing with Cloud Datastore's Protobuf API."""
import calendar
from datetime import datetime
import time

import pytz

Expand Down Expand Up @@ -37,7 +37,15 @@ def get_protobuf_attribute_and_value(val):
"""

if isinstance(val, datetime):
name, value = 'timestamp_microseconds', time.mktime(val.timetuple())
name = 'timestamp_microseconds'
# If the datetime is naive (no timezone), consider that it was
# intended to be UTC and replace the tzinfo to that effect.
if not val.tzinfo:
val = val.replace(tzinfo=pytz.utc)
# Regardless of what timezone is on the value, convert it to UTC.
val = val.astimezone(pytz.utc)
# Convert the datetime to a microsecond timestamp.
value = long(calendar.timegm(val.timetuple()) * 1e6) + val.microsecond
elif isinstance(val, Key):
name, value = 'key', val.to_protobuf()
elif isinstance(val, bool):
Expand Down Expand Up @@ -69,8 +77,9 @@ def get_value_from_protobuf(pb):
"""

if pb.value.HasField('timestamp_microseconds_value'):
timestamp = pb.value.timestamp_microseconds_value / 1e6
return datetime.fromtimestamp(timestamp).replace(tzinfo=pytz.utc)
microseconds = pb.value.timestamp_microseconds_value
return (datetime.utcfromtimestamp(0) +
datetime.timedelta(microseconds=microseconds))

elif pb.value.HasField('key_value'):
return Key.from_protobuf(pb.value.key_value)
Expand Down
5 changes: 3 additions & 2 deletions gcloud/datastore/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import calendar
from datetime import datetime
import time

Expand Down Expand Up @@ -28,7 +29,7 @@ def test_get_protobuf_attribute(self):
test_value, expected_name, actual_name))

def test_get_protobuf_value(self):
now = datetime.now()
now = datetime.utcnow()

mapping = (
(str('string'), 'string'),
Expand All @@ -37,7 +38,7 @@ def test_get_protobuf_value(self):
(long(), int()),
(float(), float()),
(bool(), bool()),
(now, time.mktime(now.timetuple())),
(now, long(calendar.timegm(now.timetuple()) * 1e6 + now.microsecond)),
(Key(), Key().to_protobuf()),
)

Expand Down

0 comments on commit bc0c1fd

Please sign in to comment.