Search code examples
pythondatetimepytz

Python datetime and tzinfo objects (changing minutes instead of hours)


I'm trying to apply a tzinfo to a datetime object.

In [1]: from datetime import datetime
In [2]: import pytz

In [3]: london = pytz.timezone("Europe/London")
In [4]: london
Out[5]: <DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>

In [6]: localized_date_object = datetime(2016, 1, 1, 11, 30, 0, 5000, london)
In [7]: localized_date_object
Out[8]: datetime.datetime(2016, 1, 1, 11, 30, 0, 5000, tzinfo=<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>)

In [9]: utc_date_object = localized_date_object.astimezone(pytz.utc)
In [10]: utc_date_object
Out[11]: datetime.datetime(2016, 1, 1, 11, 31, 0, 5000, tzinfo=<UTC>)

In [16]: paris = pytz.timezone("Europe/Paris")
In [17]: localized_date_object = datetime(2016, 1, 1, 11, 30, 0, 5000, paris)
In [18]: utc_date_object = localized_date_object.astimezone(pytz.utc)
In [19]: utc_date_object
Out[19]: datetime.datetime(2016, 1, 1, 11, 21, 0, 5000, tzinfo=<UTC>)

As you can see, it's applying delta to minutes instead of hours.
Can someone explain me what I'm doing wrong here.


Solution

  • I think that you should use CET for Paris time and UTC for London time. I am using a bit different approach but it works for me:

    from datetime import datetime
    from pytz import timezone
    
    ldo = datetime(2016, 1, 1, 11, 30, 0, 5000)
    ldo = ldo.replace(tzinfo=timezone('Europe/London'))
    
    udo = ldo.astimezone(timezone('UTC'))
    print ldo
    print udo
    
    ldo = datetime(2016, 1, 1, 11, 30, 0, 5000)
    ldo = ldo.replace(tzinfo=timezone('CET'))
    
    udo = ldo.astimezone(timezone('UTC'))
    print ldo
    print udo
    

    UPDATE:

    When you store time values there should be also stored related timezone information. IMO best practice is to store everything in UTC and convert for viewing to "user" timezone. BTW converting from UTC to Europe/Paris works flawlessly, try this:

    winter = datetime(2016, 1, 1, 11, 30, 0, 5000, tzinfo=timezone("UTC"))
    paris =  winter.astimezone(timezone("Europe/Paris"))
    print paris
    # 2016-01-01 12:30:00.005000+01:00
    
    summer = datetime(2016, 6, 1, 11, 30, 0, 5000, tzinfo=timezone("UTC"))
    paris = summer.astimezone(timezone("Europe/Paris"))
    print paris
    # 2016-06-01 13:30:00.005000+02:00