11

Given the following datetime:

d = datetime.datetime(2018, 10, 9, 8, 19, 16, 999578, tzinfo=dateutil.tz.tzoffset(None, 7200))

d.isoformat() results in the string:

'2018-10-09T08:19:16.999578+02:00'

How can I get a string with milliseconds instead of microseconds:

'2018-10-09T08:19:16.999+02:00'

strftime() will not work here: %z returns 0200 istead of 02:00 and has only %f to get microseconds, there is no placeholder for milliseconds.

cytrinox
  • 1,846
  • 5
  • 25
  • 46
  • Possible duplicate of [Using %f with strftime() in Python to get microseconds](https://stackoverflow.com/questions/6677332/using-f-with-strftime-in-python-to-get-microseconds) – deadvoid Oct 23 '18 at 08:16
  • strftime(): %z returns 0200 istead of 02:00 and has only %f to get microseconds, no placeholder for milliseconds. – cytrinox Oct 23 '18 at 08:22
  • formatting time data in datetime object to strings is still using `str.format()`, if you can get microseconds & millisecs from datetime object you can format the strings representations in any way `str.format` can do. `strftime()` is exactly the provided method for that. – deadvoid Oct 23 '18 at 08:57

2 Answers2

14

If timezone without colon is ok, you can use

d = datetime.datetime(2018, 10, 9, 8, 19, 16, 999578, 
                      tzinfo=dateutil.tz.tzoffset(None, 7200))
s = d.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + d.strftime('%z')
# '2018-10-09T08:19:16.999+0200'

For colon, you need to split the timezone and add it there yourself. %z does not produce Z either for UTC.


And Python 3.6 supports timespec='milliseconds' so you should shim this:

try:
    datetime.datetime.now().isoformat(timespec='milliseconds')
    def milliseconds_timestamp(d):
        return d.isoformat(timespec='milliseconds')

except TypeError:
    def milliseconds_timestamp(d):
        z = d.strftime('%z')
        z = z[:3] + ':' + z[3:]
        return d.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + z

Given the latter definition in Python 3.6,

>>> milliseconds_timestamp(d) == d.isoformat(timespec='milliseconds')
True

with

>>> milliseconds_timestamp(d)
'2018-10-09T08:19:16.999+02:00'
0

on 3.10 (maybe earlier, too), you can do it on a one-liner

>>> now = datetime.datetime.now()
>>> tz = datetime.timezone(datetime.timedelta(hours=-6), name="CST")
>>> now_tz = now.replace(tzinfo=tz)
>>> now_tz.isoformat("#","milliseconds")
'2023-03-02#11:02:07.592-06:00'
Max
  • 36
  • 4