views:

62

answers:

2

I want to set the .tzinfo of every datetime instance automatically as soon as it comes out of the datastore.

So if I have

class Message( db.Model ):
    creationTime = db.DateTimeProperty()
    someOtherTime = db.DateTimeProperty()

    ## I really want to define a method like this,
    ## that runs immediately AFTER an instance has
    ## been refreshed from the datastore
    def wakeup( self ): 
        self.creationTime.tzinfo = self.creationTime.replace( tzinfo=EST )
        self.someOtherTime.tzinfo = self.creationTime.replace( tzinfo=EST )

Is it possible to do this in GAE?

+1  A: 

IMHO, this is not the best way to handle timezones in GAE. From the docs:

If the datetime value has a tzinfo attribute, it will be converted to the UTC time zone for storage. Values come back from the datastore as UTC, with a tzinfo of None. An application that needs date and time values to be in a particular time zone must set tzinfo correctly when updating the value, and convert values to the timezone when accessing the value.

So,

  1. To handle creation dates or last modification dates, use auto_now and auto_now_add arguments.
  2. To display dates to users, convert them like this pacific_time = utc_time.astimezone(Pacific_tzinfo())
  3. When updating the datastore, set the tzinfo attribute using the replace function: date_from_user.replace(tzinfo=EST)
jbochi
+2  A: 

I think the best approach is for you to subclass the DateTimeProperty class and override its method make_value_from_datastore:

class EstDateTimeProperty(db.DateTimeProperty):
  def make_value_from_datastore(self, value):
    naive_utc = db.DateTimeProperty(self, value)
    aware_utc = naive_utc.replace(tzinfo=UTC)
    return aware_utc.astimezone(EST)

given suitable tzinfo objects UTC and EST of course (built by pytz or whatever). Of course you could also build a more generic "smart datetime" property class and let it set the timezone of interest from a keyword argument in its __init__, for example, if you need several different datetime attributes to use different timezones.

Alex Martelli
Exactly the right way to do this. :)
Nick Johnson