Search code examples
pythonpython-3.xdatetimepython-3.5iso8601

How to get ISO8601 string for datetime with milliseconds instead of microseconds in python 3.5


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.


Solution

  • 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'