pythonpython-3.xdatetimetimestamp

fromtimestamp returns different results


I have the following code:

import datetime

dt = 1546955400
print(datetime.datetime.fromtimestamp(dt))

When I run this code on my local machine, I get the correct (expected) time which is

2019-01-08 15:50:00.

However I tried running this exact same code on a VM and the result was 2019-01-08 13:50:00 (two hours earlier). Why is this is happening and how can I fix it so that I always get the first one regardless of where the code is running?


Solution

  • datetime.datetime.fromtimestamp() returns local time. From the documentation:

    Return the local date and time corresponding to the POSIX timestamp, such as is returned by time.time(). If optional argument tz is None or not specified, the timestamp is converted to the platform’s local date and time, and the returned datetime object is naive.

    The timestamp value is an offset in seconds from the UNIX epoch value, midnight 1 January 1970, in the UTC timezone. The local time is a system-wide configured offset from UTC, the local timezone.

    If your VM is producing unexpected results, you need to configure the timezone of the OS.

    Alternatively, ignore timezones and only deal with time in the UTC timezone. For timestamps, that means using the datetime.datetime.utcfromtimestamp() function.

    Your specific timestamp is 13:50 UTC:

    >>> dt = 1546955400
    >>> from datetime import datetime
    >>> datetime.utcfromtimestamp(dt)
    datetime.datetime(2019, 1, 8, 13, 50)
    >>> print(_)
    2019-01-08 13:50:00
    

    so your VM is either set to the UTC or the GMT timezone (the latter is currently at UTC+0, until the switch to the UK daylight saving timezone BST). Your local system is in a UTC+2 timezone, given your stated location from your profile that'd be EEE, Easter European Time.

    Another option is to create a timezone-aware timestamp by passing in a tz argument. If you have a specific UTC offset, just create a datetime.timezone() instance for that offset:

    utcplus2 = datetime.timezone(datetime.timedelta(hours=2))
    datetime.datetime.fromtimestamp(dt, utcplus2)
    

    However, it is usually better to store and operate on UTC datetime instances everywhere, and only convert to specific timezones when displaying information to users. This simplifies datetime handling as it lets you avoid a number of timezone corner cases and problems, such as mixing datetime information from different timezones and timezones with a summer and winter time distinction.