python ISO 8601 date format
Asked Answered
B

6

10

i'm trying to format the date like this,

2015-12-02T12:57:17+00:00

here's my code

time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime())

which gives this result,

2015-12-02T12:57:17+0000

i can't see any other variations of %z that can provide the correct format of +00:00 ? what's the correct way to go about this?

Blanca answered 2/12, 2015 at 14:9 Comment(7)
The offset using %z is always in the form +0000 without the symbol in between hour / minute. Is that all you need?Sassaby
No, isoformat doesn't solve it. And %z is platform dependant. I think you should come up with a parsing solution for the UTC part.Sassaby
yep, all i need to do is include the ':' symbol. so custom parsing it myself is the answer?Blanca
Unfortunately there's not a default string for that. Only %z works with the UTC and it always returns the same format without : in betweenSassaby
Wikipedia says both +00:00 and +0000 are correct and acceptable.Rapport
Yes, they are, but I think the user is trying to get an specific format for some reason. The representation is acceptable for sure.Sassaby
Python seriously has no built in support for ISO 8601?Topi
S
1

That can work for you:

Convert UTC datetime string to local datetime

I copied the code to make it easier to tackle, I indicate it's another person's answer anyway.

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print(datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z'))
print(datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z'))
print(datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z'))

t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print(t)
print(t.astimezone(EST))

I've tried it in my Python Notebook and works perfectly.

Sassaby answered 2/12, 2015 at 14:22 Comment(0)
P
4

For those looking to match datetime's ISO 8601-compliant isoformat:

from datetime import datetime

now = datetime.now()
isoformat = now.isoformat()
diy_isoformat = now.strftime("%Y-%m-%dT%H:%M:%S.%f")
assert isoformat == diy_isoformat
print(isoformat)

Will print:

2022-06-17T15:33:08.893344
Perutz answered 17/6, 2022 at 22:22 Comment(0)
S
1

That can work for you:

Convert UTC datetime string to local datetime

I copied the code to make it easier to tackle, I indicate it's another person's answer anyway.

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print(datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z'))
print(datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z'))
print(datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z'))

t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print(t)
print(t.astimezone(EST))

I've tried it in my Python Notebook and works perfectly.

Sassaby answered 2/12, 2015 at 14:22 Comment(0)
H
1

If the "%z" option is platform dependent, how about you just add your : afterwards?

t_str = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime())
t_str = t_str if t_str[-3] == ':' else  t_str[:-2] + ':' + t_str[-2:]
Haruspicy answered 2/12, 2015 at 14:32 Comment(2)
That's a good one but in one my machines it doesn't work. I should review the conversion rules to be sure why but it produces this result: '2015-12-02T16:26:30Argentina Standard Ti:me'Sassaby
I have the exact same 'problem' (same OS, same output), but since the user just wants to add a ':', then I left it like this.Haruspicy
A
0

With some help from dateutil [1] and pandas [2]

import dateutil
import pandas as pd

any_date = '20180716'
d = dateutil.parser(any_date)
# d -> datetime.datetime(2018, 7, 16, 0, 0)

d = dateutil.parser.isoparse('2018-07-16')
# d -> datetime.datetime(2018, 7, 16, 0, 0)
d = dateutil.parser.isoparse('20180716')
# d -> datetime.datetime(2018, 7, 16, 0, 0)

pd.to_datetime(d, utc=True)
# -> Timestamp('2018-07-16 00:00:00+0000', tz='UTC')
str(pd.to_datetime(d, utc=True))
# -> '2018-07-16 00:00:00+00:00'  # almost, but it's missing a T

# pandas can convert to UTC, so now we know its '+00:00Z'
pd.to_datetime(d, utc=True).strftime('%Y-%m-%dT%H:%M:%S+00:00Z')
# -> '2018-07-16T00:00:00+00:00Z'

[1] https://dateutil.readthedocs.io/en/stable/_modules/dateutil/parser/isoparser.html

[2] https://pandas.pydata.org/pandas-docs/stable/generated/pandas.to_datetime.html

Ainsworth answered 13/9, 2018 at 3:22 Comment(0)
P
0

You can trick it thanks to isoformat

t = time.strftime("%Y-%m-%dT%H:%M:%S%z", time.gmtime())
t
'2021-06-02T09:28:34+0100'
datetime.strptime(t, '%Y-%m-%dT%H:%M:%S%z').isoformat()
'2021-06-02T09:28:34+01:00'
Perimorph answered 2/6, 2021 at 9:29 Comment(0)
R
-1

I've developed this function:

def iso_8601_format(dt):
    """YYYY-MM-DDThh:mm:ssTZD (1997-07-16T19:20:30-03:00)"""

    if dt is None:
        return ""

    fmt_datetime = dt.strftime('%Y-%m-%dT%H:%M:%S')
    tz = dt.utcoffset()
    if tz is None:
        fmt_timezone = "+00:00"
    else:
        fmt_timezone = str.format('{0:+06.2f}', float(tz.total_seconds() / 3600))

    return fmt_datetime + fmt_timezone
Rheumatic answered 8/11, 2016 at 10:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.