Zona waktu parse datetime tidak konsisten dengan Python

Nov 23 2020

Ketika saya menjalankan berikut ini di Python 3.X.

import datetime

DATE_TS_FORMAT = '%Y-%m-%d %H:%M:%S.%f %Z'

date_ts = datetime.datetime(2019, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc)
date_ts = date_ts.strftime(DATE_TS_FORMAT)
print(date_ts)
date_ts = datetime.datetime.strptime(date_ts, DATE_TS_FORMAT)
date_ts = date_ts.strftime(DATE_TS_FORMAT)
print(date_ts)

saya mendapat

2019-01-02 03:04:05.000000 UTC
2019-01-02 03:04:05.000000 

Mengapa informasi zona waktu hilang dan bagaimana cara memperbaiki masalah ini?

Jawaban

2 MrFuppes Nov 24 2020 at 07:13

Memang tidak konsisten ... Intinya adalah %Zmembuat strptime menerima string tertentu (GMT, UTC dan nilai apa pun di time.tzname - docs ), tetapi tidak benar-benar membuat apa pun darinya. Ex:

from datetime import datetime

s = "2019-01-02 03:04:05.000000 UTC"
dt = datetime.strptime(s, '%Y-%m-%d %H:%M:%S.%f %Z')

print(repr(dt))
# datetime.datetime(2019, 1, 2, 3, 4, 5)

Objek datetime yang dihasilkan adalah naif; tidak ada tanda UTC lagi.

Untuk memperhitungkan perilaku ini, Anda dapat melakukan pasca-proses objek datetime, seperti

if "UTC" in s: 
    dt = dt.replace(tzinfo=timezone.utc)

(yang menurut saya agak menyakitkan ...) atau ganti "UTC" dengan sesuatu yang %zdiurai menjadi UTC 1 ,

dt = datetime.strptime(s.replace("UTC", "+00:00"), '%Y-%m-%d %H:%M:%S.%f %z')

print(repr(dt))
# datetime.datetime(2019, 1, 2, 3, 4, 5, tzinfo=datetime.timezone.utc)

(yang menurut saya agak jelek ...) atau gunakan parser yang sesuai, mis

from dateutil.parser import parse

dt = parse(s)

print(repr(dt))
# datetime.datetime(2019, 1, 2, 3, 4, 5, tzinfo=tzutc())

print(dt.strftime('%Y-%m-%d %H:%M:%S.%f %Z'))
# 2019-01-02 03:04:05.000000 UTC

(yang akan menjadi sedikit lebih lambat jika kinerja menjadi masalah ...).


1 IMO, ini juga tidak konsisten; "+00: 00" juga bisa menjadi pengimbangan UTC untuk beberapa zona waktu yang kebetulan memiliki pengimbangan UTC 0 jam pada waktu itu ...