PyMongo / Python / Airflow-将CST日期/日期时间转换为UTC并以ISO格式存储在MongoDB中吗?

问题描述

以下哪种方法是将CST日期和/或日期时间字段与DST感知设置一起转换为UTC并以Python / PyMongo的ISO格式存储在MongoDB中的正确或理想或首选方法?源日期/日期时间字段可以来自任何时区(现在我们知道其CST),我需要将它们全部转换为UTC并存储到目标MongoDB中。

根据MongoDB文档,认情况下,MongoDB将时间存储在UTC中,并将所有本地时间表示形式转换为这种形式。必须运行或报告某些未修改的本地时间值的应用程序可以将时区与UTC时间戳一起存储,并在其应用程序逻辑中计算原始本地时间。

示例:

方法1:带有时间戳记(已定义本地时区)

from datetime import datetime
import pytz
local_timezone = pytz.timezone("US/Central")
utc_datetime = local_timezone.localize(datetime.strptime ("1/2/2017 12:43 pm",'%m/%d/%Y %H:%M %p'),is_dst=True).astimezone(pytz.utc)
print(utc_datetime)
print(type(utc_datetime))

2017-01-02 18:43:00+00:00
<class 'datetime.datetime'>

没有时间戳,即只有日期:-它在时间戳中和DST 5小时中增加了6个小时的偏移值。删除或不使用 astimezone(pytz.utc),它会返回日期/时间,如2017-01-02 00:00:00-06:00,即显示-6小时的时差。我们是否应该真正使用astimezeon(pytz.utc)??

from datetime import datetime
import pytz
local_timezone = pytz.timezone("US/Central")
utc_datetime = local_timezone.localize(datetime.strptime ("1/2/2017",'%m/%d/%Y'),is_dst=True).astimezone(pytz.utc)
print(utc_datetime)
print(type(utc_datetime))

2017-01-02 06:00:00+00:00
<class 'datetime.datetime'>

方法2:带有时间戳记(未定义本地时区)

from datetime import datetime,timezone
utc_datetime=datetime.utcfromtimestamp(datetime.strptime ("1/2/2017 12:43 pm",'%m/%d/%Y %H:%M %p').replace(tzinfo = timezone.utc).timestamp())
print(utc_datetime)
print(type(utc_datetime))

2017-01-02 12:43:00
<class 'datetime.datetime'>

没有时间戳,即仅显示日期部分-没有偏移量

from datetime import datetime,timezone
utc_datetime=datetime.utcfromtimestamp(datetime.strptime ("1/2/2017",'%m/%d/%Y').replace(tzinfo = timezone.utc).timestamp())
print(utc_datetime)
print(type(utc_datetime))

2017-01-02 00:00:00
<class 'datetime.datetime'>

加载到MongoDB中后-在日期/时间戳记的末尾添加“ Z”。启动与MongoClient的连接时是否还应该添加“ tz_aware = True”?

ISOFormat -在utc时间戳上方更改为isoformat()会返回并以字符串形式(而不是日期)加载到MongoDB中。那么,我们如何确保它仍然以ISO Date格式存储在MongoDB中?

utc_datetime_iso=datetime.utcfromtimestamp(datetime.strptime ("1/2/2017",'%m/%d/%Y').replace(tzinfo = timezone.utc).timestamp()).**isoformat()**
print(utc_datetime_iso)
print(type(utc_datetime_iso))

2017-01-02T00:00:00
<class 'str'>

解决方法

我从未使用过python,因此我只能给出一些一般性注释。

从不将日期/时间值存储为字符串,请使用正确的Date对象。将日期/时间值存储为字符串通常是设计失败。

MongoDB中的所有Date值都存储在UTC中-始终且唯一。一些客户端应用程序将UTC隐式转换为本地时间并显示本地值,但是在MongoDB内部,它始终是UTC。

如果您运行db.collection.insertOne({ts: ISODate("2020-09-07T14:00:00+02:00")}),则MongoDB将存储ISODate("2020-09-07T12:00:00Z"),原始时区信息将丢失。如果需要保留原始时区,则必须将其存储在单独的字段中。

ISODate只是new Date的别名。但是,有区别。如果您未指定任何时区(例如"2020-09-07T14:00:00"),则new Date()假定为本地时间,而ISODate()假定为UTC时间。我不知道python内部使用哪种方法。

因此,new Date("2020-09-07T14:00:00")产生2020-09-07 12:00:00Z,而ISODate("2020-09-07T14:00:00")产生2020-09-07 14:00:00Z