Print datetime in ISO format without milliseconds

Csaba Toth picture Csaba Toth · Sep 17, 2015 · Viewed 10.4k times · Source

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)?

Answer

Padraic Cunningham picture Padraic Cunningham · Sep 17, 2015

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)