Why doesn't appengine auto-convert datetime to UTC when calling put()
Asked Answered
E

3

8

Here's what I'm trying to do: the user submits a time in pacific, once submitted I use .replace to set the timezone to Pacific.

Pacific = time.USTimeZone(-8, "Pacific",  "PST", "PDT")
addEvent.date = addEvent.date.replace(tzinfo=Pacific)

Once i've set the tzinfo, I'm doing a put. According to the python documentation of google appengine it says:

"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."

However, when I do a put(), i get the following error:

WARNING 2012-10-06 21:10:14,579 tasklets.py:399] initial generator _put_tasklet(context.py:264) raised NotImplementedError(DatetimeProperty date can only support UTC. Please derive a new Property to support alternative timezones.) WARNING 2012-10-06 21:10:14,579 tasklets.py:399] suspended generator put(context.py:703) raised NotImplementedError(DatetimeProperty date can only support UTC. Please derive a new Property to support alternative timezones.)

Please note I am using NDB

Ok, so after doing that I assumed that maybe NDB doesn't automatically convert it into UTC. So then I tried to convert it to UTC using the following code:

class UTC(tzinfo):
  def utcoffset(self, dt):
    return timedelta(0)
  def tzname(self, dt):
    return str("UTC")
  def dst(self, dt):
    return timedelta(0)

and now I still get the same error even after I convert the pacific time to UTC and set the tzinfo name as "UTC".

Could really use a ton of help here... thanks!

Euchromosome answered 6/10, 2012 at 21:14 Comment(0)
J
17

The solution is to remove the tzinfo completely from the time after converting to UTC.

timestamp = timestamp.replace(tzinfo=None)
Jeffry answered 7/10, 2012 at 0:25 Comment(4)
actually an example would have been really helpful.Dwightdwindle
Here is an example: do timestamp = timestamp.replace(tzinfo=None) before setting the Property to timestamp.Laundress
Wouldn't this simply remove timezone information? AFAIK ndb expects datetime to be in UTC, this would just convert a local datetime with timezone to a local datetime without timezone, no? (so instead of converting 2000-01-01T04:00:00.000000-04:00 to 2000-01-01T00:00:00.000000, it would convert it to 2000-01-01T04:00:00.000000)Tanked
@Tanked it does remove the timezone, but that's what NDB expects. The NDB layer stores timezone naive datetimes and relies on application to sort out converting from one timezone to the next.Benkley
P
0

Here my working example:

if my_date.utcoffset():
    my_date = (my_date - my_date.utcoffset()).replace(tzinfo=None)
Panda answered 10/7, 2015 at 11:14 Comment(1)
Maybe change if statement to: if my_date.utcoffset() is not None :Sile
R
0

I ran into this using http://hnrss.org/. This was my solution.

    import datetime
    from dateutil import parser

    your_date_string = 'Mon, 24 Oct 2016 16:49:47 +0000'

    your_date = parser.parse(your_date_string)
    # your_date is now a datetime.datetime object

    your_date_minus_tz = your_date.replace(tzinfo=None)

Now try your put() and you should see 2016-10-24 16:49:47 in the Cloud datastore.

Recti answered 21/12, 2016 at 15:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.