Hanpan
Hanpan

Reputation: 10261

Python / Mongoengine - Timezone missing when saved to database?

I'm having some trouble saving a date object to Mongo using MongoEngine. Here is my code:

print isodate
>>> 2014-07-01T20:00:00.000Z

import pytz
from dateutil import parser

tz = pytz.timezone('Europe/London')
start = parser.parse(isodate).replace(tzinfo=None)
start = tz.localize(start)

print start
>>> 2014-07-01 20:00:00+01:00

Localizing the date seems to work fine, but when saving to Mongo:

f = Fixture(
    start=start
)

The following strangeness is happening when I look at the Mongo document created:

{
  _id: ObjectId("53b1dfbde20b47102c824a8f"),
  start: ISODate("2014-07-01T19:00:00Z")
}

Is there any reason why the time is off by two hours, and the timezone is no longer present?

Upvotes: 2

Views: 3098

Answers (1)

ZZY
ZZY

Reputation: 3947

I feel you misunderstood date time format. Refer to W3C Date and Time Formats:

  1. Times are expressed in UTC (Coordinated Universal Time), with a special UTC designator ("Z").
  2. Times are expressed in local time, together with a time zone offset in hours and minutes. A time zone offset of "+hh:mm" indicates that the date/time uses a local time zone which is "hh" hours and "mm" minutes ahead of UTC. A time zone offset of "-hh:mm" indicates that the date/time uses a local time zone which is "hh" hours and "mm" minutes behind UTC.

"2014-07-01T20:00:00.000Z" should equal to "2014-07-01 21:00:00+01:00". So it went wrong in localizing datetime, not in saving to Mongo.

If you want to convert "....T....Z" to local time, you can try this:

print isodate
>>> 2014-07-01T20:00:00.000Z
import pytz
from dateutil import parser
local_tz = pytz.timezone('Europe/London')
local_time = parser.parse(isodate).astimezone(local_tz)
print local_time
>>> 2014-07-01 21:00:00+01:00

If you need to perform date arithmetic on local times, do one more step (refer: pytz doc):

local_tz.normalize(local_time)

Actually you can directly save "....T....Z" ISODate into Mongo without converting to local time. Since it already contains timezone info, converting is unnecessary.

Upvotes: 2

Related Questions