Print datetime in ISO format without milliseconds

Question:

I’m trying to serialize datetime in an API, but I don’t want milliseconds. What I want is here: https://en.wikipedia.org/wiki/ISO_8601"2015-09-14T17:51:31+00:00"

tz = pytz.timezone('Asia/Taipei')
dt = datetime.datetime.now()
loc_dt = tz.localize(dt)

Try A:

loc_dt.isoformat()
>> '2015-09-17T10:46:15.767000+08:00'

Try B:

loc_dt.strftime("%Y-%m-%dT%H:%M:%S%z")
>> '2015-09-17T10:46:15+0800'

The latter one is almost perfect except it’s missing the colon in the timezone part. How can I solve this without string manipulation (deleting milliseconds or adding colon)?

Asked By: Csaba Toth

||

Answers:

You can replace the microseconds with 0 and use isoformat:

import pytz
from datetime import datetime
tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt).replace(microsecond=0)
print loc_dt.isoformat()
2015-09-17T19:12:33+08:00

If you want to keep loc_dt as is do the replacing when you output:

loc_dt = tz.localize(dt)
print loc_dt.replace(microsecond=0).isoformat()

As commented you would be better passing the tz to datetime.now:

 dt = datetime.now(tz)

The reasons are discussed in pep-0495, you might also want to add an assert to catch any bugs when doing the replace:

 ssert loc_dt.resolution >= timedelta(microsecond=0)
Answered By: Padraic Cunningham

Since python 3.6, datetime.isoformat accepts a timespec keyword to pick a precision. This argument gives the smallest time unit you want to be included in the output:

>>> loc_dt.isoformat()
'2022-10-21T19:59:59.991999+08:00'

>>> loc_dt.isoformat(timespec='seconds')
'2022-10-21T19:59:59+08:00'

>>> loc_dt.isoformat(timespec='milliseconds')
'2022-10-21T19:59:59.991+08:00'

Notice how the time is truncated and not rounded.

You can also use timespec to remove seconds/minutes:

>>> loc_dt.isoformat(timespec='minutes')
'2022-10-21T19:59+08:00'

>>> loc_dt.isoformat(timespec='hours')
'2022-10-21T19+08:00'

This all assume you ran the following setup script beforehand:

from datetime import datetime
import pytz

tz = pytz.timezone('Asia/Taipei')
dt = datetime.now()
loc_dt = tz.localize(dt)

Also note that this works without timezone:

>>> from datetime import datetime
>>> now = datetime.now()
>>> now.isoformat(timespec='minutes')
>>> '2022-10-21T19:59'
Answered By: cglacet
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.