925

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
kabr8
  • 196
  • 1
  • 14
VeryNewToPython
  • 9,283
  • 3
  • 13
  • 3

17 Answers17

1337

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'))
Steven Kryskalla
  • 12,904
  • 1
  • 35
  • 41
Michał Niklas
  • 48,759
  • 16
  • 62
  • 100
  • 143
    `.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 Nov 23 '13 at 01:08
  • 11
    @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? – davidhood2 Nov 22 '16 at 09:16
  • 4
    @davidhood2 take a system where python has no access to [the tz database](https://en.wikipedia.org/wiki/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 Nov 22 '16 at 14:10
  • 3
    @davidhood2: I've posted [my own answer that demonstrates the `pytz` solution](http://stackoverflow.com/a/40769643/4279). – jfs Nov 23 '16 at 16:31
  • 6
    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. – wordsforthewise Jun 13 '17 at 18:28
  • 1
    Is there an advantage of using `strftime` over `"{:%Y-%m-%d %H:%M:%S}".format(dateobj)`? – Martin Thoma Aug 10 '17 at 13:02
  • According to Python documentation `__format__()` is same as `strftime()` but I simply prefer `strftime()`. – Michał Niklas Aug 11 '17 at 09:19
  • 1
    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. https://stackoverflow.com/q/31548132/2960555 – unknownerror Oct 30 '17 at 09:44
  • What if I want to include milliseconds? – User Oct 20 '18 at 23:48
  • @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). – jfs Dec 27 '18 at 15:41
  • or just `datetime.datetime.utcfromtimestamp(1398385815)` – prayagupd Apr 18 '19 at 19:40
273
>>> from datetime import datetime
>>> datetime.fromtimestamp(1172969203.1)
datetime.datetime(2007, 3, 4, 0, 46, 43, 100000)

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

Daniel
  • 3,227
  • 1
  • 14
  • 19
169

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

rkachach
  • 13,862
  • 5
  • 35
  • 55
  • 2
    import datetime, pytz datetime.datetime(1990, 1, 1, tzinfo=pytz.utc) – y.selivonchyk Jun 23 '17 at 18:09
  • 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) – jfs Sep 07 '20 at 15:58
  • `ValueError: year 53085 is out of range` – alper Feb 11 '21 at 17:36
83
>>> 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'
John La Rooy
  • 263,347
  • 47
  • 334
  • 476
  • 10
    `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. – jfs Nov 23 '13 at 01:30
76

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))  
jfs
  • 346,887
  • 152
  • 868
  • 1,518
54

In Python 3.6+:

import datetime

timestamp = 1579117901
value = datetime.datetime.fromtimestamp(timestamp)
print(f"{value:%Y-%m-%d %H:%M:%S}")

Output (in UTC)

2020-01-15 19:51:41

Explanation

Bonus

To save the date to a string then print it, use this:

my_date = f"{value:%Y-%m-%d %H:%M:%S}"
print(my_date)
Daniel F
  • 11,845
  • 6
  • 75
  • 100
Contango
  • 65,385
  • 53
  • 229
  • 279
37

For a human readable timestamp from a UNIX timestamp, I have used this in scripts before:

import os, datetime

datetime.datetime.fromtimestamp(float(os.path.getmtime("FILE"))).strftime("%B %d, %Y")

Output:

'December 26, 2012'

Jared Burrows
  • 50,718
  • 22
  • 143
  • 180
33

Other than using time/datetime package, pandas can also be used to solve the same problem.Here is how we can use pandas to convert timestamp to readable date:

Timestamps can be in two formats:

  1. 13 digits(milliseconds) - To convert milliseconds to date, use:

    import pandas
    result_ms=pandas.to_datetime('1493530261000',unit='ms')
    str(result_ms)
    
    Output: '2017-04-30 05:31:01'
    
  2. 10 digits(seconds) - To convert seconds to date, use:

    import pandas
    result_s=pandas.to_datetime('1493530261',unit='s')
    str(result_s)
    
    Output: '2017-04-30 05:31:01'
    
shubham
  • 456
  • 4
  • 7
27

You can convert the current time like this

t=datetime.fromtimestamp(time.time())
t.strftime('%Y-%m-%d')
'2012-03-07'

To convert a date in string to different formats.

import datetime,time

def createDateObject(str_date,strFormat="%Y-%m-%d"):    
    timeStamp = time.mktime(time.strptime(str_date,strFormat))
    return datetime.datetime.fromtimestamp(timeStamp)

def FormatDate(objectDate,strFormat="%Y-%m-%d"):
    return objectDate.strftime(strFormat)

Usage
=====
o=createDateObject('2013-03-03')
print FormatDate(o,'%d-%m-%Y')

Output 03-03-2013
Nick
  • 1,677
  • 3
  • 20
  • 32
23
timestamp ="124542124"
value = datetime.datetime.fromtimestamp(timestamp)
exct_time = value.strftime('%d %B %Y %H:%M:%S')

Get the readable date from timestamp with time also, also you can change the format of the date.

Alberto Bonsanto
  • 15,350
  • 8
  • 56
  • 90
Rishabh Jhalani
  • 739
  • 6
  • 17
  • 7
    What does this answer add to [this](https://stackoverflow.com/a/21578729/8254699) answer? – kocica Dec 30 '18 at 10:42
  • 1
    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. – Timothy C. Quinn May 12 '19 at 16:01
8

Note that utcfromtimestamp can lead to unexpected results since it returns a naive datetime object. Python treats naive datetime as local time - while UNIX time refers to UTC.

This ambiguity can be avoided by setting the tz argument in fromtimestamp:

from datetime import datetime, timezone

dtobj = datetime.fromtimestamp(1284101485, timezone.utc)

>>> print(repr(dtobj))
datetime.datetime(2010, 9, 10, 6, 51, 25, tzinfo=datetime.timezone.utc)

Now you can format to string, e.g. an ISO8601 compliant format:

>>> print(dtobj.isoformat(timespec='milliseconds').replace('+00:00', 'Z'))
2010-09-10T06:51:25.000Z
MrFuppes
  • 11,829
  • 3
  • 17
  • 46
6
import datetime
temp = datetime.datetime.fromtimestamp(1386181800).strftime('%Y-%m-%d %H:%M:%S')
print temp
itsaruns
  • 499
  • 2
  • 9
  • 16
6

Another way that this can be done using gmtime and format function;

from time import gmtime
print('{}-{}-{} {}:{}:{}'.format(*gmtime(1538654264.703337)))

Output: 2018-10-4 11:57:44

h3xus
  • 63
  • 1
  • 4
1

i just successfully used:

>>> type(tstamp)
pandas.tslib.Timestamp
>>> newDt = tstamp.date()
>>> type(newDt)
datetime.date
nimmy
  • 29
  • 1
0

quick and dirty one liner:

'-'.join(str(x) for x in list(tuple(datetime.datetime.now().timetuple())[:6]))

'2013-5-5-1-9-43'

eqzx
  • 4,167
  • 3
  • 30
  • 48
  • 3
    Or more concisely: '-'.join(map(str, datetime.datetime.now().timetuple()[:6])) – Jelle Zijlstra Jun 11 '14 at 04:23
  • 2
    @JelleZijlstra Eh, I much prefer the generator expression over map. – crhodes Aug 24 '15 at 11:08
  • 6
    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. – madoki Feb 09 '16 at 18:18
  • 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. https://stackoverflow.com/a/458001/209246 – eqzx Feb 22 '18 at 22:07
0

You can use easy_date to make it easy:

import date_converter
my_date_string = date_converter.timestamp_to_string(1284101485, "%B %d, %Y")
Raphael Amoedo
  • 3,485
  • 3
  • 23
  • 33
  • 5
    Every programming has it's own date and time converters. One should never have to use mods/frameworks for this – Jos Faber Dec 09 '15 at 14:55
  • 1
    `strptime` and `strftime` isn't intuitive... And even not readable... But I understand and respect your opinion – Raphael Amoedo Dec 09 '15 at 18:06
  • 6
    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. – Hejazzman Dec 22 '15 at 23:57
  • 1
    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 – Jos Faber Jan 19 '16 at 10:28
0

Use the following codes, I hope it will solve your problem.

import datetime as dt

print(dt.datetime.fromtimestamp(int("1284101485")).strftime('%Y-%m-%d %H:%M:%S'))
Rachel Gallen
  • 25,819
  • 19
  • 69
  • 75
Deepak
  • 1