【问题标题】:Have a correct datetime with correct timezone有一个正确的日期时间和正确的时区
【发布时间】:2015-05-08 18:30:35
【问题描述】:

我使用feedparser 来获取RSS 数据。 这是我的代码:

>>> import datetime
>>> import time
>>> import feedparser

>>> d=feedparser.parse("http://.../rss.xml")

>>> datetimee_rss = d.entries[0].published_parsed

>>> datetimee_rss
time.struct_time(tm_year=2015, tm_mon=5, tm_mday=8, tm_hour=16, tm_min=57, tm_sec=39, tm_wday=4, tm_yday=128, tm_isdst=0)

>>> datetime.datetime.fromtimestamp(time.mktime(datetimee_rss))
datetime.datetime(2015, 5, 8, 17, 57, 39)

在我的时区 (FR) 中,实际日期是 May, 8th, 2015 18:57。

在 RSS XML 中,值为<pubDate>Fri, 08 May 2015 18:57:39 +0200</pubDate>

当我将其解析为日期时间时,我得到了2015, 5, 8, 17, 57, 39。

如何让2015, 5, 8, 18, 57, 39 不被黑,而只需配置正确的时区?

编辑:

通过这样做:

>>> from pytz import timezone

>>> datetime.datetime.fromtimestamp(time.mktime(datetimee_rss),tz=timezone('Euro
pe/Paris'))
datetime.datetime(2015, 5, 8, 17, 57, 39, tzinfo=<DstTzInfo 'Europe/Paris' CEST+2:00:00 DST>)

我得到了更好的东西,但是,它似乎不适用于脚本的其余部分,我得到了很多 TypeError: can't compare offset-naive and offset-aware datetimes 错误。

【问题讨论】:

  • 我不知道提要解析器如何处理这些日期,但生成的日期时间和时间元组实际上根本不知道 tz。
  • 除了您的 Python 问题,您应该注意 RSS 提要中的时间戳通常非常混乱,默认情况下您可能不应该“信任”它们。一些服务通过使用他们的“发现”日期来欺骗新闻项目。
  • @JulienGenestoux 我已经想到了。如果我在现场环境中遇到太多复杂情况,我会试试看 :-) 谢谢!

标签: python datetime rss feedparser


【解决方案1】:

feedparser 确实提供了原始日期时间字符串(只需从属性名称中删除_parsed 后缀),因此如果您知道字符串的格式,您可以自己将其解析为可识别 tz 的日期时间对象。

例如,使用您的代码,您可以像这样获取 tz-aware 对象:

datetime.datetime.strptime(d.entries[0].published, '%a, %d %b %Y %H:%M:%S %z')

有关strptime()的更多参考,请参阅https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior

编辑:由于 Python 2.x 不支持 %z 指令,请改用 python-dateutil

pip install python-dateutil

然后

from dateutil import parser
datetime_rss = parser.parse(d.entries[0].published)

https://dateutil.readthedocs.org/en/latest/的文档

【讨论】:

  • 我收到以下错误:ValueError: 'z' is a bad directive in format '%a, %d %b %Y %H:%M:%S %z'
  • 如果你使用的是 Python 2.x,它不支持%z。请检查上面的更新答案。
  • 它在控制台中工作,但给定的日期时间格式在处理其他日期时间时会产生异常,例如“datatime.now()”:TypeError: can't compare offset-naive and offset-aware datetimes(与我编辑的问题相同)。是否可以将“offset-aware”转换为“offset-naive”?
  • @Blusky 您无法将 tz 感知的日期时间对象与幼稚的对象进行比较,因为后者没有任何时区信息。你知道你的天真日期时间对象的时区是什么吗?
  • local tz 是 'Europe/Paris',日期时间由 datetime.datetime.now() 提供。现在没有 tz 是不是很奇怪?
【解决方案2】:

feedparser 以 UTC 时区返回时间。将time.mktime() 应用于它是不正确的(除非您的本地时区是UTC,否则它不是)。你应该改用calendar.timegm():

import calendar
from datetime import datetime

utc_tuple = d.entries[0].published_parsed
posix_timestamp = calendar.timegm(utc_tuple)
local_time_as_naive_datetime_object = datetime.frometimestamp(posix_timestamp) # assume non-"right" timezone

RSS feeds may use many different dates formats;我会将日期解析留给feedparser 模块。

如果您想获取本地时间作为感知日期时间对象:

from tzlocal import get_localzone # $ pip install tzlocal

local_timezone = get_localzone()
local_time = datetime.frometimestamp(posix_timestamp, local_timezone) # assume non-"right" timezone

【讨论】:

    【解决方案3】:

    试试这个:

    >>> import os
    >>> os.environ['TZ'] = 'Europe/Paris'
    >>> time.tzset()
    >>> time.tzname
    ('CET', 'CEST')
    

    【讨论】:

    • 我收到以下错误:AttributeError: 'module' object has no attribute 'tzset'。显然,tzset 仅适用于 Linux。我在 Windows 上运行,并且希望脚本是多平台的。还有其他想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 2021-02-17
    • 2019-03-08
    • 2014-05-23
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多