views:

298

answers:

2

Hi guys!

I am working in a small app in the Google App Engine (Python), which uses the Google Data API in order to create a new calendar in a Google account and populate it with some events.

The events that I am using are parsed from another place, and they have the date in the Europe/Stockholm timezone, (I think it is CEST or CET).

Therefore, first I create a Python struct_time with (for example) this:

start = strptime("2009-11-16 10:15", "%Y-%m-%d %H:%M")

Python's doc says that there I could use the flag %Z in order to specify the timezone, and in fact it works in my Python interpreter... but it totally fails in the Google App Engine server (both localhost and deploy). It is something not new, as I have seen here.

Since I am using the Google Data API, and it needs the times in UTC/GMT format, I need a way to convert from the Europe/Stockholm local time to the UTC/GMT, without use the %Z flag in strptime ... (and something more smart than just subtract one hour to each date...)

Thank you in advance one more time :)

A: 

after parsing your object into datetime, you have to add timezone. for that you need to create class derived from the datetime.tzinfo

import datetime as dt
class SomeZone(dt.tzinfo):
    # a helper class to quickly create simple timezones - give gmt_offset
    def __init__(self, gmt_offset):
        dt.tzinfo.__init__(self)
        self.gmt_offset = gmt_offset        
    def utcoffset(self, dtime): return dt.timedelta(hours=self.gmt_offset)
    def dst(self, dtime): return dt.timedelta(0)
    def tzname(self, dtime): return None

start = strptime("2009-11-16 10:15", "%Y-%m-%d %H:%M")
start.replace(tzinfo=SomeZone(your_offset_here))

et voila, now it is a datetime with timezone. from here google will take over, as the datetime fields are zone aware and on storage will store it in utc.

just remember about daylight savings and everything.

if you would like to scavenge around, i'm using the class described up there here

tm_lv
+1  A: 

I posted something related to this subject on my blog last year. Basically, it converts all times to UTC when storing them in the datastore, and attaches the UTC timezone to them when read out. You can feel free to modify it to then convert the values to whatever local timezone you want.

This code sample may be out of date — I haven't used appengine in a long time. But I hope it will help you in some way.

import pytz

class TzDateTimeProperty(db.DateTimeProperty):
    def get_value_for_datastore(self, model_instance):
        if model_instance.posted_at.tzinfo is None:
            model_instance.posted_at = model_instance.posted_at.replace(tzinfo=pytz.utc)
        else:
            model_instance.posted_at = model_instance.posted_at.astimezone(pytz.utc)
        return super(TzDateTimeProperty, self).get_value_for_datastore(model_instance)
    def make_value_from_datastore(self, value):
        value = super(TzDateTimeProperty, self).make_value_from_datastore(value)
        if value.tzinfo is None:
            value = value.replace(tzinfo=pytz.utc)
        else:
            value = value.astimezone(pytz.utc)
        return value

I also recommend the excellent pytz library; it provides timezone objects for just about every useful timezone. (I'd link to it, but spam prevention is stopping me. Just Google for it.)

inklesspen