Convert Between Isoformat String and datetime in Python
In Python, you can handle date and time information with the datetime module from the standard library.
The datetime module provides methods, such as isoformat() and fromisoformat(), for converting between ISO format (ISO 8601) strings and datetime objects.
For an introduction to datetime, date, and time objects, as well as conversion between specific format strings and datetime objects, refer to the following article.
Convert date and time objects to isoformat strings: isoformat()
To convert date and time objects to ISO format (ISO 8601) strings, use the isoformat() method on date, time, and datetime objects.
Convert a date object to an isoformat string
Consider the following date object.
import datetime
d = datetime.date(2023, 4, 1)
print(d)
# 2023-04-01
print(type(d))
# <class 'datetime.date'>
You can convert a date object to an isoformat string using isoformat().
print(d.isoformat())
# 2023-04-01
print(type(d.isoformat()))
# <class 'str'>
Convert a time object to an isoformat string
Consider the following time object.
t = datetime.time(5, 0, 30, 1000)
print(t)
# 05:00:30.001000
print(type(t))
# <class 'datetime.time'>
You can convert a time object to an isoformat string using isoformat().
print(t.isoformat())
# 05:00:30.001000
print(type(t.isoformat()))
# <class 'str'>
You can control the elements included in the result using the timespec argument. By default, timespec is set to 'auto', which sets timespec to 'seconds' if microseconds are 0, and to 'microseconds' otherwise.
print(t.isoformat('hours'))
# 05
print(t.isoformat('minutes'))
# 05:00
print(t.isoformat('seconds'))
# 05:00:30
print(t.isoformat('milliseconds'))
# 05:00:30.001
print(t.isoformat('microseconds'))
# 05:00:30.001000
Convert a datetime object to an isoformat string
Consider the following datetime object.
dt = datetime.datetime(2023, 4, 1, 5, 0, 30, 1000)
print(dt)
# 2023-04-01 05:00:30.001000
print(type(dt))
# <class 'datetime.datetime'>
You can convert a datetime object to an isoformat string using isoformat().
print(dt.isoformat())
# 2023-04-01T05:00:30.001000
print(type(dt.isoformat()))
# <class 'str'>
The default character separating the date and time is T. You can specify a different single character using the first argument sep. Providing a string with two or more characters will cause an error.
print(dt.isoformat(' '))
# 2023-04-01 05:00:30.001000
print(dt.isoformat('x'))
# 2023-04-01x05:00:30.001000
# print(dt.isoformat('xx'))
# TypeError: isoformat() argument 1 must be a unicode character, not str
As with the time object, you can control the elements included in the result using the timespec argument. By default, timespec is set to 'auto', which sets timespec to 'seconds' if microseconds are 0, and to 'microseconds' otherwise.
print(dt.isoformat(timespec='hours'))
# 2023-04-01T05
print(dt.isoformat(timespec='minutes'))
# 2023-04-01T05:00
print(dt.isoformat(timespec='seconds'))
# 2023-04-01T05:00:30
print(dt.isoformat(timespec='milliseconds'))
# 2023-04-01T05:00:30.001
print(dt.isoformat(timespec='microseconds'))
# 2023-04-01T05:00:30.001000
To convert a datetime object to a date-only or time-only string, first use the date() or time() methods to create the corresponding object, and then call the isoformat() method on that object.
print(dt.date().isoformat())
# 2023-04-01
print(dt.time().isoformat())
# 05:00:30.001000
Convert isoformat strings to date and time objects: fromisoformat()
To convert an ISO format (ISO 8601) string to date, time, and datetime objects, use the fromisoformat() method of the date, time, and datetime classes.
fromisoformat() was added in Python 3.7. Additionally, as described later, it supports the ISO 8601 basic format starting from Python 3.11.
Convert an isoformat string to a date object
You can convert an isoformat string to a date object using fromisoformat().
d = datetime.date.fromisoformat('2023-04-01')
print(d)
# 2023-04-01
print(type(d))
# <class 'datetime.date'>
An error will be raised if the year, month, or day is omitted or has an incorrect number of digits. The year should have 4 digits, while the month and day should each have 2 digits, zero-padded.
# print(datetime.date.fromisoformat('2023-04'))
# ValueError: Invalid isoformat string: '2023-04'
# print(datetime.date.fromisoformat('2023-4-1'))
# ValueError: Invalid isoformat string: '2023-4-1'
Convert an isoformat string to a time object
You can convert an isoformat string to a time object using fromisoformat().
t = datetime.time.fromisoformat('05:00:30.001000')
print(t)
# 05:00:30.001000
print(type(t))
# <class 'datetime.time'>
If minutes, seconds, or microseconds are omitted, they will be treated as 0.
print(datetime.time.fromisoformat('05'))
# 05:00:00
An error will be raised if the hours, minutes, and seconds are not represented as zero-padded two-digit numbers.
# print(datetime.time.fromisoformat('5:00:30'))
# ValueError: Invalid isoformat string: '5:00:30'
Convert an isoformat string to a datetime object
You can convert an isoformat string to a datetime object using fromisoformat().
dt = datetime.datetime.fromisoformat('2023-04-01T05:00:30.001000')
print(dt)
# 2023-04-01 05:00:30.001000
print(type(dt))
# <class 'datetime.datetime'>
Any single character other than T between the date and time is acceptable, but two or more characters will cause an error.
print(datetime.datetime.fromisoformat('2023-04-01x05:00:30.001000'))
# 2023-04-01 05:00:30.001000
# print(datetime.datetime.fromisoformat('2023-04-01xx05:00:30.001000'))
# ValueError: Invalid isoformat string: '2023-04-01xx05:00:30.001000'
If minutes and seconds are omitted, they will be treated as 0.
print(datetime.datetime.fromisoformat('2023-04-01T05'))
# 2023-04-01 05:00:00
print(datetime.datetime.fromisoformat('2023-04-01'))
# 2023-04-01 00:00:00
Like with date and time objects, an error will occur if the number of digits is incorrect. Zero-padding is required.
# print(datetime.datetime.fromisoformat('2023-4-1T5:00'))
# ValueError: Invalid isoformat string: '2023-4-1T5:00'
To convert a string containing both date and time to date and time objects, first convert it to a datetime object, and then call the date() and time() methods on that object.
s = '2023-04-01T05:00:30.001000'
# print(datetime.date.fromisoformat(s))
# ValueError: Invalid isoformat string: '2023-04-01T05:00:30.001000'
d = datetime.datetime.fromisoformat(s).date()
print(d)
# 2023-04-01
print(type(d))
# <class 'datetime.date'>
ISO 8601 basic and extended formats
ISO 8601 has an extended format that includes hyphens - and colons : as separators, and a basic format that does not.
- Basic format:
20230401T050030.001000 - Extended format:
2023-04-01T05:00:30.001000
fromisoformat() supports basic format from Python 3.11
Starting from Python 3.11, fromisoformat() supports the basic format.
print(datetime.date.fromisoformat('20230401'))
# 2023-04-01
print(datetime.time.fromisoformat('050030.001000'))
# 05:00:30.001000
print(datetime.datetime.fromisoformat('20230401T050030.001000'))
# 2023-04-01 05:00:30.001000
In earlier versions, you need to specify an appropriate format string for strptime().
print(datetime.datetime.strptime('20230401T050030.001000', '%Y%m%dT%H%M%S.%f'))
# 2023-04-01 05:00:30.001000
Convert between basic and extended format strings
As demonstrated above, isoformat() outputs an extended format string. To obtain a basic format string, use string manipulation methods.
For example, use replace() to remove hyphens - and colons :.
s = '2023-04-01T05:00:30.001000'
print(s.replace('-', '').replace(':', ''))
# 20230401T050030.001000
To exclude milliseconds and smaller units, use the split() method to separate the string at the decimal point ., and select the first element.
print(s.split('.')[0].replace('-', '').replace(':', ''))
# 20230401T050030
To convert a basic format string to an extended format, first convert the basic format string to a datetime object, and then use the isoformat() method to obtain the extended format string. As mentioned above, use fromisoformat() for Python 3.11 and later, and strptime() for earlier versions.
s_basic = '20230401T050030.001000'
print(datetime.datetime.fromisoformat(s_basic).isoformat())
# 2023-04-01T05:00:30.001000
Handling timezone information
When converting a string without timezone information using fromisoformat() as shown in the previous examples, the tzinfo attribute will be None.
s = '2023-04-01T05:00:30.001000'
dt = datetime.datetime.fromisoformat(s)
print(dt)
# 2023-04-01 05:00:30.001000
print(dt.tzinfo)
# None
If a string includes timezone information like +09:00 at the end, the tzinfo attribute will have a value.
s = '2023-04-01T05:00:30.001000+09:00'
dt = datetime.datetime.fromisoformat(s)
print(dt)
# 2023-04-01 05:00:30.001000+09:00
print(dt.tzinfo)
# UTC+09:00
When the tzinfo attribute has a value, the isoformat() method appends a timezone string to the end of the output string according to that value.
print(dt.isoformat())
# 2023-04-01T05:00:30.001000+09:00
Isoformat string with Z
When representing UTC (Coordinated Universal Time), a trailing Z is added.
Python 3.11 and later
Starting from Python 3.11, fromisoformat() correctly handles trailing Z.
s = '2023-04-01T05:00:30.001000Z'
dt = datetime.datetime.fromisoformat(s)
print(dt)
# 2023-04-01 05:00:30.001000+00:00
print(dt.tzinfo)
# UTC
Before Python 3.11
In versions prior to Python 3.11, a string with a trailing Z will cause an error with fromisoformat().
To handle a trailing Z, you can replace it with +00:00. In this case, the tzinfo attribute will contain the appropriate timezone information.
s = '2023-04-01T05:00:30.001000Z'
dt_utc = datetime.datetime.fromisoformat(s.replace('Z', '+00:00'))
print(dt_utc)
# 2023-04-01 05:00:30.001000+00:00
print(dt_utc.tzinfo)
# UTC
If you remove the trailing Z, the tzinfo attribute will be None. This approach can be used if timezone information is not necessary for your use case.
dt_none = datetime.datetime.fromisoformat(s.replace('Z', ''))
print(dt_none)
# 2023-04-01 05:00:30.001000
print(dt_none.tzinfo)
# None