4

When syncing between iOS and my Python GAE backend, I would like to utilise the timestamp for a clean solution.

According to my research this is the best way to create a reliable timestamp:

calendar.timegm((datetime.datetime.now()).utctimetuple())

where I get an integer like this: 1382375236

When on the backend, I would like to additionally save the last_updated datetime derived from the timestamp. That is human readable and good for a quick check.

def before_put(self):
    self.last_updated = datetime.utcfromtimestamp(self.timestamp)

However this fails with an error:

TypeError: a float is required

What is the best way of solving this in an accurate way?

UPDATE:

I also found this suggestion here: The solution would be dividing it by 1e3.

In my case this gives me a strange date:

>>> datetime.datetime.utcfromtimestamp(1382375236 / 1e3)
datetime.datetime(1970, 1, 16, 23, 59, 35, 236000)

UPDATE 2

The entire model is:

class Record(ndb.Model):
    user = ndb.KeyProperty(kind=User)
    record_date = ndb.DateProperty(required=True)
    rating = ndb.IntegerProperty(required=True)
    notes = ndb.TextProperty()
    last_updated = ndb.DateTimeProperty(required=True)
    timestamp = ndb.IntegerProperty(required=True)

    def __repr__(self):
        return '<record_date %r>' % self.record_date

    def before_put(self):
        self.last_updated = datetime.utcfromtimestamp(self.timestamp)

    def after_put(self):
        pass

    def put(self, **kwargs):
        self.before_put()
        super(Record, self).put(**kwargs)
        self.after_put()
Community
  • 1
  • 1
Houman
  • 64,245
  • 87
  • 278
  • 460
  • You have problems saving it in the Datastore? can you show also the Model that you are trying to save this value to? – Lipis Oct 21 '13 at 16:33
  • Sure thing. It is now updated. Thanks – Houman Oct 21 '13 at 16:39
  • Is there any particular reason that you are not using `auto_now=True` on the DateTimeProperty. Second why override put, you have pre and post put hooks to acheive what you are doing with out overriding put() yourself. See hook methods https://developers.google.com/appengine/docs/python/ndb/modelclass#Model__pre_put_hook – Tim Hoffman Oct 22 '13 at 10:43
  • Tim, you told me not to use it. http://stackoverflow.com/q/19379133/92153 ;-) Due unit testing, it was causing too much trouble. I was under the impression I had to override `put` and call its super class, if I wanted to use custom `before_put` and `after_put`. Thanks for input. I will remove `put` then and leave the other two. – Houman Oct 22 '13 at 11:47

1 Answers1

4

As you mentioned, calendar.timegm returns a unix timestamp in the form of a integer. A unix timestamp is always the number of seconds since the 1st of January, 1970. However, the precision of the timestamp depends on the implementation: it could be represented as a integer, a long, a float, or a double.

It seems that, in your particular version of python, datetime.utcfromtimestamp is expecting a float, so you should pass the number of seconds as a float:

datetime.utcfromtimestamp(float(self.timestamp))

The suggestion you found refers to a different representation of time - the number of milliseconds since the 1st of January, 1970. This is not a unix timestamp, per definition.

loopbackbee
  • 21,962
  • 10
  • 62
  • 97