Search code examples
pythonpython-3.xdatetimetimezonepytz

python timezone problem with the same timezone


Why I get different result timezone in the one file with the almost same datetime constructions?

print(datetime.datetime.now(pytz.timezone('Europe/Moscow')))
>>> 2020-05-31 12:55:04.778210+03:00

print(datetime.datetime(2020, 5, 31, 12, 54, 0, 0,  pytz.timezone('Europe/Moscow')))
>>> 2020-05-31 12:54:00+02:30

Solution

  • the problem lies within the fact that pytz uses a different time zone model than the Python standard lib. Here's a blog post by Paul Ganssle explaining the issue.

    The correct way to do this with pytz would be to use the localize method of its timezone class:

    import datetime
    import pytz
    print(datetime.datetime.now(pytz.timezone('Europe/Moscow')))
    >>> 2020-05-31 15:15:45.559007+03:00
    
    print(pytz.timezone('Europe/Moscow').localize(datetime.datetime(2020, 5, 31, 15, 16, 0, 0)))
    >>> 2020-05-31 15:16:00+03:00
    

    While datetime.datetime.now(pytz.timezone('Europe/Moscow')) correctly creates a datetime object with the defined timezone, datetime.datetime(2020, 5, 31, 12, 54, 0, 0, pytz.timezone('Europe/Moscow')) creates a naive datetime object first and then replace the timezone. Avoid replace when working with pytz, use localize instead.

    An alternative to pytz is dateutil. Here, the above operation is more straight forward since dateutil uses the standard lib's time zone model:

    import dateutil
    
    print(datetime.datetime.now(dateutil.tz.gettz('Europe/Moscow')))
    >>> 2020-05-31 15:13:55.967773+03:00
    
    print(datetime.datetime(2020, 5, 31, 15, 14, 0, 0,  dateutil.tz.gettz('Europe/Moscow')))
    >>> 2020-05-31 15:14:00+03:00