简体   繁体   中英

How to convert date string to ISO8601 standard?

using dateutil I was able to genrate ISO8601 of type YYYY-MM-DDThh:mm:ssTZD but I want the format 'YYYY-MM-DDThh:mm:ss.sssTZD' eg '2015-05-13T18:05:55.320-07:00'

My code is

from datetime import datetime
from dateutil.parser import *
from dateutil.tz import *
import dateutil
import time

ts = time.time()
utc_offset = (datetime.fromtimestamp(ts) -
           datetime.utcfromtimestamp(ts)).total_seconds()

now = parse("11/10/09 11:20 PM")
now = now.replace(tzinfo=tzoffset('PDT', utc_offset))

and output is 2009-11-10T23:20:00-07:00 how would I get output like 2009-11-10T23:20:00.000-07:00

Python's datetime.strftime method can print microseconds:

ISO_FORMAT_MICROS = "%Y-%m-%dT%H:%M:%S.%f%z"
now.strftime(ISO_FORMAT_MICROS)

returns

'2009-11-10T23:20:00.000000-0700'

Rounding to microseconds

The milliseconds part is a little tricky. The following code is a refinement of RoadieRich's solution :

from datetime import datetime, timedelta

def datetime_to_iso(dt):
    fmt = "{time.year:04}-{time.month:02}-{time.day:02}T{time.hour:02}:{time.minute:02}:{time.second:02}.{millisecond:03}{tz}"

    ## handle rounding up to the next second
    if dt.microsecond >= 999500:
        dt -= timedelta(microseconds=dt.microsecond)
        dt += timedelta(seconds=1)

    return fmt.format(time=dt, millisecond=int(round(dt.microsecond/1000.0)), tz=dt.strftime("%z"))

For example:

In [130]: d1 = datetime(2015,03,15,2,05,59,999999)

In [131]: datetime_to_iso(d1)
Out[131]: '2015-03-15T02:06:00.000'

In [132]: d2 = datetime(2015,03,15,2,05,59,456789)

In [133]: datetime_to_iso(d2)
Out[133]: '2015-03-15T02:05:59.457'

Use datetime.isoformat() :

>>> now = datetime.now(tzoffset('EDT', -4*60*60))
>>> print(now.isoformat())
2015-05-15T07:08:34.478784-04:00

Note that the isoformat method omits microseconds if the value is 0 (as in your example parsed time. If you must have factional seconds in your output use %f in a format string:

>>> print(now.strftime("%y-%m-%dT%H:%M:%S.%f%z"))
15-05-15T07:35:00.000000-0400

If you need milli seconds, you'll have to write your own formatting routine:

def format_time_with_milliseconds(time):
    fmt = "{time.year:04}-{time.month:02}-{time.day:02}T{time.hour:02}:{time.minute:02}:{time.second:02}.{millisecond:03}{tz}"
    return fmt.format(time=time, millisecond=int(round(time.microsecond/1000)), tz=time.strftime("%z")) 

The same format that can parse that format:

>>> from datetime import datetime
>>> ts='2015-05-13T18:05:55.320-0700'
>>> tf="%Y-%m-%dT%H:%M:%S.%f%z"
>>> dt=datetime.strptime(ts, tf)
>>> dt
datetime.datetime(2015, 5, 13, 18, 5, 55, 320000, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))

Can also print it:

>>> dt.strftime(tf)
'2015-05-13T18:05:55.320000-0700'

Note the lack of the ':' in the tz however.

You can also use isoformat() to print your target:

>>> dt.isoformat()
2015-05-13T18:05:55.320000-07:00

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM