Forums

timezone conversions with dateutil

Hi,

I have the following settings:

TIME_ZONE = 'UTC'
USE_TZ = True

I have a form allowing the user to put year, month, day, hour, minute and his timezone. I'm trying to convert the user date and time into UTC date and time

view.py

from dateutil import tz

dayf = form.cleaned_data['dayf']
monthf = form.cleaned_data['monthf']
yearf = form.cleaned_data['yearf']
hourf = form.cleaned_data['hourf']
minutef = form.cleaned_data['minutef']
timezonef = form.cleaned_data['timezonef']


from_zone = tz.gettz(timezonef)
to_zone = tz.gettz('UTC')

time_event_user = datetime.datetime(int(yearf), int(monthf), int(dayf), int(hourf), int(minutef))
time_event_user = time_event_user.replace(tzinfo=from_zone)

time_event_utc = time_event_user.astimezone(to_zone)

Now if I put timezone "Europe/Berlin" and today 8pm I will get both for time_event_user and time_eevnt_utc 7pm What's wrong here? Why is

time_event_user = time_event_user.replace(tzinfo=from_zone)

not working properly?

Let's see if we can figure it out. At this point:

time_event_user = datetime.datetime(int(yearf), int(monthf), int(dayf), int(hourf), int(minutef))

we have time_event_user = 8PM, tz=UTC

next we do:

 time_event_user = time_event_user.replace(tzinfo=from_zone)

so now time_event_user = 8PM, tz=europe. (which is the same time as 7pm utc)

next we do

time_event_utc = time_event_user.astimezone(to_zone)

so time_event_utc = 7pm utc

So those two variables represent the same absolute time, I imagine they might compare equal... how are you checking that both are 7pm utc?

I save both time_event_user and time_event_utc into an external mongodb database as datetime objects.

so I save

 time_event_user = time_event_user.replace(tzinfo=from_zone)

and in my database time_event_user looks like

2014-11-24 19:00:00.000Z

Could that be to do with the way your mongodb library handles saving datetime objects? Have you ever managed to save a non-UTC datetime?

What happens if you do some debug prints of those two datetimes?

Indeed ! When I do:

        f = open('/home/KBrothers/crossLFG/groupbuilder/test.txt','w')
        f.write(str(time_event_user))
        f.write(str(time_event_utc))
        f.close()

I get

        2014-11-24 22:00:00+01:00
        2014-11-24 21:00:00+00:00

and my MongoDB says

        time_event_user     2014-11-24 21:00:00.000Z

How is that possible?

is that still with an 8PM input? or with a 9PM now? if so, maybe mongo doesn't like storing datetimes in multiple timezones? or maybe the library you're using to talk to mongo converts everything to utc by default?

Yes that's correct. Thanks for the hints. From the docs:

Prior to PyMongo version 1.7, the correct way is to only save naive datetime instances, and to save all dates as UTC. In versions >= 1.7, the driver will automatically convert aware datetimes to UTC before saving them. By default, datetimes retrieved from the server (no matter what version of the driver you’re using) will be naive and represent UTC. In newer versions of the driver you can set the MongoClient tz_aware parameter to True, which will cause all datetime instances returned from that MongoClient to be aware (UTC). This setting is recommended, as it can force application code to handle timezones properly.

Warning Be careful not to save naive datetime instances that are not UTC (i.e. the result of calling datetime.datetime.now()). Something like pytz can be used to convert dates to localtime after retrieving them from the database.