这是使用 dateutil 设置时区的正确方法吗?
Is this the right way to set a timezone with dateutil?
>>> import dateutil.parser, dateutil.tz as tz
>>> dateutil.parser.parse('2017-08-09 10:45 am').replace(tzinfo=tz.gettz('America/New_York'))
datetime.datetime(2017, 8, 9, 10, 45, tzinfo=tzfile('/usr/share/zoneinfo/America/New_York'))
那是真的我们应该为解析设置默认时区的方式吗?我已经阅读了 parser and examples 的文档,但我似乎找不到任何关于 "This is how to set the default timezone for dateutil.parser.parse" 或类似内容的内容。
因为虽然 有效 ,但如果提供了区域,在某些情况下它会做错事。这是否意味着我们应该这样做?
>>> d = dateutil.parser.parse('2017-08-09 10:45 am +06:00')
>>> d = d.replace(tzinfo=d.tzinfo or tz.gettz('America/Chicago'))
因为那也很笨重。
解析时设置默认时区的推荐方法是什么?
充实 Paul 的评论 - 因为 datetime
必须在 至少 年月日,dateutil 已经有一个它使用的默认值:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2017, 10, 13, 15, 16, 13, 548750)
>>> dateutil.parser.parse('2017')
datetime.datetime(2017, 10, 13, 0, 0)
鉴于此,适当的选择是创建一个 default
包含时区并且只是当前日期或任何有意义的日期:
>>> dateutil.parser.parse('2017', default=datetime(2017, 10, 13, tzinfo=tz.gettz('America/New_York')))
当然你可以将默认值存储为合理的东西,比如 default_datetime
之类的,然后它变成:
>>> dateutil.parser.parse('2017', default=default_datetime)
基本上有两种 "correct" 方法可以做到这一点。您可以看到这是在 dateutil
的问题跟踪器上作为 Issue #94 提出的,并且 "set a default time zone" 被确定为超出范围,因为这可以通过解析器返回的信息(因此无需将其构建到解析器本身)。两种方式是:
提供一个 default
有时区的日期。如果您不关心 default
日期是什么,您可以只指定一些日期文字并完成它。如果你希望行为与 dateutil
的默认行为基本相同(替换 "today's date at midnight" 中缺失的元素),你必须有一些样板:
from datetime import datetime, time
from dateutil import tz, parser
default_date = datetime.combine(datetime.now(),
time(0, tzinfo=tz.gettz("America/New_York")))
dt = parser.parse(some_dt_str, default=default_date)
将第二种方法与 .replace
一起使用:
from dateutil import parser
def my_parser(*args, default_tzinfo=tz.gettz("America/New_York"), **kwargs):
dt = parser.parse(*args, **kwargs)
return dt.replace(tzinfo=dt.tzinfo or default_tzinfo)
最后一个可能比第一个稍微干净一些,但是如果 运行 处于紧密循环中(因为第一个只需要创建一次默认日期),性能会略有下降,但是 dateutil
的解析器实际上很慢,所以如果你运行在一个紧密的循环中使用它,额外的日期构造可能是你最少的问题。
>>> import dateutil.parser, dateutil.tz as tz
>>> dateutil.parser.parse('2017-08-09 10:45 am').replace(tzinfo=tz.gettz('America/New_York'))
datetime.datetime(2017, 8, 9, 10, 45, tzinfo=tzfile('/usr/share/zoneinfo/America/New_York'))
那是真的我们应该为解析设置默认时区的方式吗?我已经阅读了 parser and examples 的文档,但我似乎找不到任何关于 "This is how to set the default timezone for dateutil.parser.parse" 或类似内容的内容。
因为虽然 有效 ,但如果提供了区域,在某些情况下它会做错事。这是否意味着我们应该这样做?
>>> d = dateutil.parser.parse('2017-08-09 10:45 am +06:00')
>>> d = d.replace(tzinfo=d.tzinfo or tz.gettz('America/Chicago'))
因为那也很笨重。
解析时设置默认时区的推荐方法是什么?
充实 Paul 的评论 - 因为 datetime
必须在 至少 年月日,dateutil 已经有一个它使用的默认值:
>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2017, 10, 13, 15, 16, 13, 548750)
>>> dateutil.parser.parse('2017')
datetime.datetime(2017, 10, 13, 0, 0)
鉴于此,适当的选择是创建一个 default
包含时区并且只是当前日期或任何有意义的日期:
>>> dateutil.parser.parse('2017', default=datetime(2017, 10, 13, tzinfo=tz.gettz('America/New_York')))
当然你可以将默认值存储为合理的东西,比如 default_datetime
之类的,然后它变成:
>>> dateutil.parser.parse('2017', default=default_datetime)
基本上有两种 "correct" 方法可以做到这一点。您可以看到这是在 dateutil
的问题跟踪器上作为 Issue #94 提出的,并且 "set a default time zone" 被确定为超出范围,因为这可以通过解析器返回的信息(因此无需将其构建到解析器本身)。两种方式是:
提供一个
default
有时区的日期。如果您不关心default
日期是什么,您可以只指定一些日期文字并完成它。如果你希望行为与dateutil
的默认行为基本相同(替换 "today's date at midnight" 中缺失的元素),你必须有一些样板:from datetime import datetime, time from dateutil import tz, parser default_date = datetime.combine(datetime.now(), time(0, tzinfo=tz.gettz("America/New_York"))) dt = parser.parse(some_dt_str, default=default_date)
将第二种方法与
.replace
一起使用:from dateutil import parser def my_parser(*args, default_tzinfo=tz.gettz("America/New_York"), **kwargs): dt = parser.parse(*args, **kwargs) return dt.replace(tzinfo=dt.tzinfo or default_tzinfo)
最后一个可能比第一个稍微干净一些,但是如果 运行 处于紧密循环中(因为第一个只需要创建一次默认日期),性能会略有下降,但是 dateutil
的解析器实际上很慢,所以如果你运行在一个紧密的循环中使用它,额外的日期构造可能是你最少的问题。