Converting unix timestamp string to readable date

1,369,899

Solution 1

Use datetime module:

from datetime import datetime
ts = int('1284101485')

# if you encounter a "year is out of range" error the timestamp
# may be in milliseconds, try `ts /= 1000` in that case
print(datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S'))

Solution 2

>>> from datetime import datetime
>>> datetime.fromtimestamp(1172969203.1)
datetime.datetime(2007, 3, 4, 0, 46, 43, 100000)

Taken from http://seehuhn.de/pages/pdate

Solution 3

The most voted answer suggests using fromtimestamp which is error prone since it uses the local timezone. To avoid issues a better approach is to use UTC:

datetime.datetime.utcfromtimestamp(posix_time).strftime('%Y-%m-%dT%H:%M:%SZ')

Where posix_time is the Posix epoch time you want to convert

Solution 4

>>> import time
>>> time.ctime(int("1284101485"))
'Fri Sep 10 16:51:25 2010'
>>> time.strftime("%D %H:%M", time.localtime(int("1284101485")))
'09/10/10 16:51'

Solution 5

There are two parts:

  1. Convert the unix timestamp ("seconds since epoch") to the local time
  2. Display the local time in the desired format.

A portable way to get the local time that works even if the local time zone had a different utc offset in the past and python has no access to the tz database is to use a pytz timezone:

#!/usr/bin/env python
from datetime import datetime
import tzlocal  # $ pip install tzlocal

unix_timestamp = float("1284101485")
local_timezone = tzlocal.get_localzone() # get pytz timezone
local_time = datetime.fromtimestamp(unix_timestamp, local_timezone)

To display it, you could use any time format that is supported by your system e.g.:

print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"))
print(local_time.strftime("%B %d %Y"))  # print date in your format

If you do not need a local time, to get a readable UTC time instead:

utc_time = datetime.utcfromtimestamp(unix_timestamp)
print(utc_time.strftime("%Y-%m-%d %H:%M:%S.%f+00:00 (UTC)"))

If you don't care about the timezone issues that might affect what date is returned or if python has access to the tz database on your system:

local_time = datetime.fromtimestamp(unix_timestamp)
print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f"))

On Python 3, you could get a timezone-aware datetime using only stdlib (the UTC offset may be wrong if python has no access to the tz database on your system e.g., on Windows):

#!/usr/bin/env python3
from datetime import datetime, timezone

utc_time = datetime.fromtimestamp(unix_timestamp, timezone.utc)
local_time = utc_time.astimezone()
print(local_time.strftime("%Y-%m-%d %H:%M:%S.%f%z (%Z)"))

Functions from the time module are thin wrappers around the corresponding C API and therefore they may be less portable than the corresponding datetime methods otherwise you could use them too:

#!/usr/bin/env python
import time

unix_timestamp  = int("1284101485")
utc_time = time.gmtime(unix_timestamp)
local_time = time.localtime(unix_timestamp)
print(time.strftime("%Y-%m-%d %H:%M:%S", local_time)) 
print(time.strftime("%Y-%m-%d %H:%M:%S+00:00 (UTC)", utc_time))  
Share:
1,369,899
Admin
Author by

Admin

Updated on July 08, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a string representing a unix timestamp (i.e. "1284101485") in Python, and I'd like to convert it to a readable date. When I use time.strftime, I get a TypeError:

    >>>import time
    >>>print time.strftime("%B %d %Y", "1284101485")
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: argument must be 9-item sequence, not str
    
  • jfs
    jfs over 10 years
    .fromtimestamp() might fail for past dates if a local timezone had different utc offset. You need a historic timezone database such as provided by pytz module (or your OS). Or just work in UTC and use .utcfromtimestamp().
  • jfs
    jfs over 10 years
    time.ctime() and time.localtime() might fail for past dates if a local timezone had different utc offset. You need a historic timezone database such as provided by pytz module (or your OS). Or just work in UTC and use time.gmtime(). datetime might provide wider date range so datetime.utcfromtimestamp() could be used instead of time functions.
  • Jelle Zijlstra
    Jelle Zijlstra almost 10 years
    Or more concisely: '-'.join(map(str, datetime.datetime.now().timetuple()[:6]))
  • crhodes
    crhodes almost 9 years
    @JelleZijlstra Eh, I much prefer the generator expression over map.
  • Jos Faber
    Jos Faber over 8 years
    Every programming has it's own date and time converters. One should never have to use mods/frameworks for this
  • Raphael Amoedo
    Raphael Amoedo over 8 years
    strptime and strftime isn't intuitive... And even not readable... But I understand and respect your opinion
  • Hejazzman
    Hejazzman over 8 years
    That one should "never have to use" is wrong. It depends on the language and the quality of the built-in libs. Javascript has moments.js and Java had Joda time which both are more popular than the respective built-in date and time conversion utils (so much that Joda time later influenced Java 8's updated standard libs). That said, unless the question calls for nice third-party libraries, it's preferable to give an answer based on the standard library.
  • Jos Faber
    Jos Faber over 8 years
    I stand corrected @NikosVentouras. I've just had the "JS Date in IE behaves differently" issue for the first time. So I ended up using moment.js
  • madoki
    madoki over 8 years
    What kind of date format is '2013-5-5-1-9-43' ? I've never seen this format anywhere as a valid representation of a date/time.
  • davidhood2
    davidhood2 over 7 years
    @J.F.Sebastian You've mentioned this might fail in a couple of comments - please could you elaborate as to why it would fail for a past dates/times? (Judging by the upvotes, many people both agree with you and see this as straightforward) Surely any unix timestamp has a simple equivalent date/time?
  • jfs
    jfs over 7 years
    @davidhood2 take a system where python has no access to the tz database (Windows), set your local timezone to a timezone that had a different UTC offset in the past (e.g. Europe/Moscow), call fromtimestamp() with timestamps from the past (2011-). Compare the results with values computed using pytz. If it is unclear; ask a separate Stack Overflow question.
  • jfs
    jfs over 7 years
  • wordsforthewise
    wordsforthewise almost 7 years
    An import point is this takes a timestamp in seconds since the epoch; if you have milliseconds you have to divide by 1000 as I just found out.
  • y.selivonchyk
    y.selivonchyk almost 7 years
    import datetime, pytz datetime.datetime(1990, 1, 1, tzinfo=pytz.utc)
  • Martin Thoma
    Martin Thoma almost 7 years
    Is there an advantage of using strftime over "{:%Y-%m-%d %H:%M:%S}".format(dateobj)?
  • Michał Niklas
    Michał Niklas almost 7 years
    According to Python documentation __format__() is same as strftime() but I simply prefer strftime().
  • unknownerror
    unknownerror over 6 years
    If you are getting ValueError: year VALUE is out of range, that means you are working with milliseconds(Unix timestamp is 13 digits). The above function works only if Unix timestamp in seconds. If you are working with milliseconds, divide that value by 1000. stackoverflow.com/q/31548132/2960555
  • eqzx
    eqzx over 6 years
    can you elaborate on what qualifies this as an invalid representation @madoki ? do you mean nonstandard? The primary advantage it has over most other answers is the ability to include it in a file or directory path, as spaces and colons are not in the set of standard unix directory characters. see e.g. stackoverflow.com/a/458001/209246
  • User
    User over 5 years
    What if I want to include milliseconds?
  • jfs
    jfs over 5 years
    @User pass a float e.g., if you have 1234 milliseconds then pass 1.234 seconds (it is easy to divide by 1000 on the decimal system: just move the decimal dot 3 positions to the left).
  • kocica
    kocica over 5 years
    What does this answer add to this answer?
  • prayagupa
    prayagupa about 5 years
    or just datetime.datetime.utcfromtimestamp(1398385815)
  • Timothy C. Quinn
    Timothy C. Quinn about 5 years
    Please add a warning related to issue of local timezone assumption. Best practices in programming is to store timestamps as UTC times instead of local timestamps. But this example above will return the wrong time if the local timezone is not UTC.
  • azzamsa
    azzamsa over 4 years
    It should be the most voted answer if you care about local time.
  • bjornasm
    bjornasm almost 4 years
    Great answer, but whish you showed how you could save the date to a string, and not just print it: value.strftime('%Y-%m-%d %H:%M:%S')
  • Contango
    Contango almost 4 years
    @bjornasm Sure, updated answer with a similar method to achieve this.
  • jfs
    jfs over 3 years
    beware, unix time might be different from posix time in (rare) cases e.g., TZ=right/UTC date vs. TZ=UTC date is Mon 7 Sep 15:58:05 UTC 2020 vs. Mon 7 Sep 15:58:32 UTC 2020 (the difference may change depending on the number of leap seconds)
  • alper
    alper over 3 years
    ValueError: year 53085 is out of range
  • Barlas Apaydin
    Barlas Apaydin about 3 years
    if you get ValueError: year xxx is out of range error divide your timestamp to /1000 stackoverflow.com/a/31548402/1428241
  • Rachel Gallen
    Rachel Gallen about 3 years
    add an explanation re, why this code will solve the problem to improve your answer.
  • essexboyracer
    essexboyracer about 3 years
    f-strings are specific to Python v3.6+ - stackoverflow.com/a/51262245/4442148
  • ENV
    ENV almost 3 years
    @John La Rooy is there a similar method to convert back from date-time string back to the Unix timestamp?
  • ENV
    ENV almost 3 years
    @jfs is there a similar method to convert back from date-time string back to the Unix timestamp?
  • jfs
    jfs almost 3 years
    @ENV: once you've parsed your input time string into an aware datetime object, just call its .timestamp() method. How to convert the time string depends on its format -- it is ambiguous in the general case but there are many solution for various cases.
  • sidgeon smythe
    sidgeon smythe almost 3 years
    @alper In such cases, likely one has a timestamp in milliseconds; try dividing by 1000. Or by 1000000 if the timestamp is in microseconds.
  • FObersteiner
    FObersteiner over 2 years
    The output is not UTC but local time, unless you set the tz argument in fromtimestamp, e.g. to datetime.timezone.utc.
  • Contango
    Contango over 2 years
    @MrFruppes Correct. Edited answer on 2022-01-17 to fix this.