Date and time handling
Resources
- datetime module in Python.
- strftime cheatsheet
- unixtimestamp.com converter.
- Unix time on Wikipedia.
- ISO 8061 standard on Wikipedia - date, time, and datetime.
- Date
2022-01-08
- Date and time in UTC
2022-01-08T08:18:20+00:00
2022-01-08T08:18:20Z
20220108T081820Z
- Date
Current time
Today
Get a date
object for today’s date - using date.today
method.
datetime.date.today()
# datetime.date(2021, 5, 8)
Now
Get a datetime
object for the current date and time - using datetime.today
or datetime.now
methods:
datetime.datetime.today()
# datetime.datetime(2021, 11, 2, 20, 21, 10, 742033)
datetime.datetime.now()
# datetime.datetime(2021, 11, 2, 20, 21, 10, 753648)
datetime.datetime.utcnow()
# datetime.datetime(2021, 11, 2, 18, 21, 10, 760241)
Note - both today
and now
give the same result, but only now
can accept a time zone. In the examples above, the code was run at GMT+0200. So when datetime.utcnow
method is run, that gives the time at GMT+0000, which is the UTC time and is 2 hours before the others.
Get a float for the current time, using time
module.
time.time()
# 1635876799.357939
The long way using datetime
.
datetime.datetime.today().timestamp()
# 1635876799.357939
Time
Unix timestamp:
time.time()
# 1641638542.2153149
C time:
time.ctime()
'Sat Jan 8 12:42:28 2022'
Create
Date
x = datetime.date(2021, 1, 2)
# datetime.date(2021, 1, 2)
str(x)
# '2021-01-02'
Datetime
Create a datetime from a date - defaults to midnight.
datetime.datetime(2021, 1, 2)
# datetime.datetime(2021, 1, 2, 0, 0)
str(datetime.datetime(2021, 1, 2))
'2021-01-02 00:00:00'
Create a datetime object:
x = datetime.datetime(2021, 1, 2, 3, 40)
# datetime.datetime(2021, 1, 2, 3, 40)
str(x)
# '2021-01-02 03:40:00'
If you want to be more explicit:
datetime.datetime(year=2021, month=1, day=2)
# datetime.datetime(2021, 1, 2, 0, 0)
From the docs:
datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints.
Attributes
datetime.datetime.ATTRIBUTE
e.g.
n = datetime.datetime.now()
n.hour
# 11
n.year
# 2021
n.month
# 5
n.day
# 8
n.hour
# 11
n.minute
# 30
n.second
# 51
Format
Format a datetime value as a string.
See Format codes for what symbols to use when formatting or parsing.
Format datetime as built-in string
x = datetime.datetime.now()
Use ISO-8601 format:
x.isoformat()
# '2021-11-02T20:19:57.928643'
You can also stringify the object for the same result:
str(x)
# '2021-11-02T20:19:57.928643'
Use C time:
dt = datetime.datetime.now()
dt.ctime()
# 'Sat Jan 8 12:41:22 2022'
Format datetime as custom string
Convert from date or datetime object to a custom string.
Using .strftime
where the f
is for “format”.
Supply a custom format.
MY_DATETIME.strftime(MY_FORMAT)
e.g.
x = datetime.datetime.now()
# datetime.datetime(2021, 5, 8, 11, 30, 51, 733268)
Showing functionality of a few areas:
x.strftime('%Y/%m/%d - %b %y - %H:%M:%S')
# '2021/05/08 - May 21 - 11:05:51'
Short date and 24-hour time:
x.strftime('%Y-%m-%d %H:%M')
'2021-11-02 20:11'
Parse
Parse a string as a datetime object.
See Format codes for what symbols to use when formatting or parsing.
Parse string as datetime
Parse from a string to datetime object.
Using strptime
, where the p
stands for “parse”.
datetime.datetime.strptime(DATETIME_STRING, CUSTOM_FORMAT)
e.g.
Set the time.
dt = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
# datetime.datetime(2006, 11, 21, 16, 30)
str(dt)
# '2006-11-21 16:30:00'
Omit time and it will be midnight.
dt = datetime.datetime.strptime('2021-01-02', '%Y-%m-%d')
# datetime.datetime(2021, 1, 2, 0, 0)
str(dt)
# '2021-01-02 00:00:00'
dt = datetime.datetime.strptime('12/05/19', '%m/%d/%y')
# datetime.datetime(2019, 12, 5, 0, 0)
str(dt)
'2019-12-05 00:00:00'
There is no strptime
method on datetime.date
, but you can convert a datetime to date. See the next section.
Parse ISO 8061 datetime string
Parse ISO 8061 format date and time with timezone.
e.g.
2020-01-24T08:37:37+00:00
The response is a timezone-aware datetime object.
v = "2020-01-24T08:37:37+00:00"
datetime.datetime.fromisoformat(v)
# datetime.datetime(2020, 1, 24, 8, 37, 37, tzinfo=datetime.timezone.utc)
Parse long format
e.g.
Thu, 30 Aug 2018 13:14:09 GMT
From my aggregit repo.
See SO answers.
import datetime
from email.utils import mktime_tz, parsedate_tz
def parse_datetime(standard_datetime):
"""
Parse a standardised datetime string to a datetime object.
:param standard_datetime: datetime value as a string.
e.g. 'Thu, 30 Aug 2018 13:14:09 GMT'
:return: timezone-aware datetime object in UTC time.
Printing this out will reflect in the system's timezone.
e.g. entering time 12:00 for +0000 timezone shows as 14:00
if printing in a system set to +0200 timezone,
whether doing `str(obj)` or `str(obj.hour)`.
"""
time_tuple = parsedate_tz(standard_datetime)
timestamp = mktime_tz(time_tuple)
return datetime.datetime.fromtimestamp(timestamp)
Format codes
Some useful combinations:
- Long day.
%A, %-d %B %Y Sunday, 1 January 2021
- Short day.
%Y-%M-%d 2021-01-01
- 12-hour time
%I:%M %p 11:01 AM 11:01 PM
- 24-hour time
%H:%M:%Ss 11:01:01s 23:01:01s
- Time zone.
%z +0000 -0400
Conversion
Move between date formats. For converting to and from strings, see section above.
Convert from date to datetime
Get a date object from datetime object.
dt.date()
e.g. Current date.
dt = datetime.datetime(2022, 1, 8, 12, 34, 14, 214702)
d = dt.date()
# datetime.date(2022, 1, 8)
Parse a string of a date (just omit the time) then convert from datetime to date.
dt = datetime.datetime.strptime('12/05/19', '%m/%d/%y')
d = dt.date()
# datetime.date(2019, 12, 5)
str(d)
'2019-12-05'
Convert from date to datetime
There aren’t anything methods on a date
object we can use.
So you need to make a new datetime
object from the date
object’s properties.
Omit the time:
d = datetime.date(2022, 1, 8)
dt = datetime.datetime(year=d.year, month=d.month, day=d.day)
# datetime.datetime(2022, 1, 8, 0, 0)
Then set it after if you need to:
dt.replace(hour=12, minute=34)
datetime.datetime(2022, 1, 8, 12, 34)
Specify a time at creation:
datetime.datetime(year=y.year, month=y.month, day=y.day,
hour=12, minute=34, second=56)
# datetime.datetime(2022, 1, 8, 12, 34, 56)
datetime.datetime(year=y.year, month=y.month, day=y.day,
hour=12, minute=34)
# datetime.datetime(2022, 1, 8, 12, 34)
Convert from datetime to time
dt.time()
e.g.
dt = datetime.datetime.now()
# datetime.datetime(2022, 1, 8, 13, 8, 1, 493063)
dt.time()
# datetime.time(13, 8, 1, 493063)
Convert from unix timestamp to datetime
Pass in an integer or float.
Use datetime.datetime.fromtimestamp
to get datetime or datetime.date.fromtimestamp
to get a date.
e.g.
datetime.datetime.fromtimestamp(1403602426.0)
# datetime.datetime(2014, 6, 24, 11, 33, 46)
Convert unix timestamp to date and time
Convert duration in seconds to equivalent value in days, hours, minutes or seconds. Using maths and without using datetime
, in case you ever had to do this or something similar.
duration = 1234
d = duration / (24 * 60 * 60)
h = duration / (60 * 60) % 24
m = duration / 60 % 60
s = duration % 60
d, h, m, s
# (0.014282407407407407, 0.3427777777777778, 20.566666666666666, 34)
Timedelta
Or time difference or duration
You can add and subtract date or datetime objects from each other.
How many days
Get timedelta in days between two dates.
datetime.date(2021, 1, 5) - datetime.date(2021, 1, 1)
# datetime.timedelta(days=4)
Difference in seconds
x = datetime.datetime.now()
y = datetime.datetime.now()
y - x
# datetime.timedelta(seconds=2, microseconds=693039)
x - y
# datetime.timedelta(days=-1, seconds=86397, microseconds=306961)
Find difference between a timestamp and now
Lets say you want to get age.
x = datetime.date.today() - datetime.date(1990, 1, 2)
# datetime.timedelta(days=11449)
x.days
# 11449
# Appromiate age in years.
round(x.days / 365.25, 2)
# 31.35
x.total_seconds()
989193600.0
In one line from the CLI:
$ python3 -c 'import datetime; print( round( ( datetime.date.today() - datetime.date(1989, 6, 3) ).days / 365.25, 2 ) )'
31.93
Future time
Let’s say you want something to expire in 30 minutes from now and you want to know when that is.
n = datetime.datetime.now()
str(n)
# '2021-05-08 11:30:51.733268'
expire_at = n + datetime.timedelta(minutes=30)
str(expire_at)
# '2021-05-08 12:00:51.733268'
You can be more precise with hours, minutes and seconds.
d = datetime.timedelta(hours=1, minutes=2, seconds=3)
# datetime.timedelta(seconds=3723)
str(d)
'1:02:03'
Or with days.
d = datetime.timedelta(days=1000,seconds=10)
# datetime.timedelta(days=1000, seconds=10)
str(d)
# '1000 days, 0:00:10'
Time zone
You can also set a time zone with a tzinfo
object. See the pytz library, which can be installed a package.
The preferred way of dealing with times is to always work in UTC, converting to localtime only when generating output to be read by humans.
Here adding tzinfo
to a datetime
object, though this does not work properly for timezones which use daylight savings.
import pytz
datetime.datetime(2002, 10, 27, 6, 0, 0, tzinfo=pytz.utc)
datetime.datetime.now(tzinfo=pytz.utc)
My example:
from datetime import datetime
import pytz
from pytz import timezone
FMT = "%Y-%m-%d %H:%M:%S %Z%z"
dt = datetime(2002, 10, 27, 6, 0, 0)
amsterdam = timezone("Europe/Amsterdam")
loc_dt = amsterdam.localize(dt)
# Naiive
print(dt)
# 2002-10-27 06:00:00
# Timezone aware
print(loc_dt.strftime(FMT))
# 2002-10-27 06:00:00 CET+0100
# Note straight printing gives you offset but not the symbol.
print(str(loc_dt))
# 2002-10-27 06:00:00+01:00
# Display in another timezone.
utc = pytz.utc
print(loc_dt.astimezone(tz=utc))
# 2002-10-27 05:00:00+00:00