来自字符串的日期时间时区

Posted

技术标签:

【中文标题】来自字符串的日期时间时区【英文标题】:Datetime Timezones from String 【发布时间】:2021-02-04 16:21:05 【问题描述】:

我试图弄清楚如何通过使用变量来使日期时间对象感知。我抓取用户的时区并将其传递给要使用的表单。

我尝试了以下两种方法,但都没有成功

timezone_variable = "Europe/London"
new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                            int(time_hour), int(date_minute), tzinfo=timezone_variable)

new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                            int(time_hour), int(date_minute), tzinfo=timezone.timezone_variable)

这会给我TypeError: tzinfo argument must be None or of a tzinfo subclass, not type 'str'的错误

时区并不总是预先知道的,因此不可能简单地将参数设为tzinfo=timezone.utc

【问题讨论】:

【参考方案1】:

您可以使用 pytz 从字符串创建时区对象:

>>> from pytz import timezone
>>> timezone("Europe/London")
<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>

这可以在datetime.datetime() 构造函数中用作tzinfo 参数。如果需要,请按照文档中的说明使用 localize() 函数。

【讨论】:

【参考方案2】:

使用dateutil 或Python 3.9 的zoneinfo

from datetime import datetime
from dateutil.tz import gettz
# from zoneinfo import ZoneInfo # Python 3.9

date_year, date_month, date_day, time_hour, date_minute = 2020, 10, 21, 10, 21

timezone_variable = gettz("Europe/London") # ZoneInfo("Europe/London") # Python 3.9

new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                        int(time_hour), int(date_minute), tzinfo=timezone_variable)
print(new_datetime) 
# 2020-10-21 10:21:00+01:00 
print(repr(new_datetime))
# datetime.datetime(2020, 10, 21, 10, 21, tzinfo=tzfile('GB-Eire'))

# with zoneinfo:
# datetime.datetime(2020, 10, 21, 10, 21, tzinfo=zoneinfo.ZoneInfo(key='Europe/London'))

注意:您可以直接创建datetime 对象。如果您使用pytz(Python 3.9 已弃用),您必须使用时区对象的localize 方法。否则,您将得到LMT(当地时间):

import pytz
timezone_variable = pytz.timezone("Europe/London")

# not what you want (most of the time...):
new_datetime = datetime(int(date_year), int(date_month), int(date_day),
                        int(time_hour), int(date_minute), tzinfo=timezone_variable)
print(repr(new_datetime))
# datetime.datetime(2020, 10, 21, 10, 21, tzinfo=<DstTzInfo 'Europe/London' LMT-1 day, 23:59:00 STD>)

旁注:有趣的是,dateutil 返回Europe/London 的deprecated GB-Eire 时区名称。不过是对的,不用担心。

【讨论】:

谢谢。你知道是否有任何方法可以本地化一个有意识的日期时间吗?我有一个 UTC 时区的日期时间,我想将其转换为本地时区(事先未知)。我在尝试使用本地化时遇到错误,正如它所说的那样,并且正如你所说的 .replace 函数提供了 LMT。 @101892781:回答here ;-) 非常感谢您回答这两个问题,非常感谢! :)

以上是关于来自字符串的日期时间时区的主要内容,如果未能解决你的问题,请参考以下文章

什么足以将来自多个时区的日期/时间存储在数据库中以进行准确计算?

来自毫秒和时区的Javascript日期[重复]

使用 pytz 将日期时间从一个时区转换为另一个时区

JavaScript:将 UTC 日期时间转换为传递时区的日期时间

使用 Noda Time 在时区之间转换

Python 字符串到 Django 时区(知道日期时间)