Python datetime.replace()上传Firebase Firestore时出现异常行为
问题原因
- Firestore存储的所有时间均为UTC时区,控制台会将其转换为你浏览器的本地时区(此处为UTC+1)显示。
- 你的代码中
datetime.now()返回的是无时区信息的naive datetime,在Cloud Functions默认的UTC运行环境中,这个naive时间被视为UTC时间。 - 执行
replace(hour=0)后得到的是UTC时区当天0点的naive时间,调用astimezone()会为其添加UTC时区标记。Firestore存储该UTC时间后,控制台转换为UTC+1时区就显示为01:00 UTC+1,与预期不符。
解决方案
你需要先获取带明确时区信息的当前时间,再进行时间修改,避免时区混淆:
方案1:基于当前进程时区(推荐,适配函数部署区域)
@https_fn.on_call(region='europe-west1', vpc_connector='connector1', vpc_connector_egress_settings=options.VpcEgressSetting('ALL_TRAFFIC')) def testing(req: https_fn.CallableRequest): firestore_client: google.cloud.firestore.Client = firestore.client() visit_collection = firestore_client.collection('visits') # 先获取带时区的当前时间 now_with_tz = datetime.now().astimezone() visit_collection.add( { 'test1': now_with_tz, 'test2': now_with_tz.replace(hour=0, minute=0, second=0, microsecond=0), }, 'test' )
方案2:指定固定时区(更严谨,不受运行环境影响)
如果需要严格绑定Europe/Paris时区(europe-west1对应时区),可以明确指定:
from zoneinfo import ZoneInfo # Python 3.9+ 内置,无需额外安装 @https_fn.on_call(region='europe-west1', vpc_connector='connector1', vpc_connector_egress_settings=options.VpcEgressSetting('ALL_TRAFFIC')) def testing(req: https_fn.CallableRequest): firestore_client: google.cloud.firestore.Client = firestore.client() visit_collection = firestore_client.collection('visits') tz = ZoneInfo('Europe/Paris') now_with_tz = datetime.now(tz) visit_collection.add( { 'test1': now_with_tz, 'test2': now_with_tz.replace(hour=0, minute=0, second=0, microsecond=0), }, 'test' )
修改后,test2会生成预期的UTC+1时区当天0点,Firestore存储对应的UTC时间(前一天23:00),控制台显示为2024年3月23日 00:00:00 UTC+1。
内容的提问来源于stack exchange,提问作者jaakdentrekhaak
相关产品推荐
相关产品推荐

