1

我正在尝试转换 Facebook start_time 的时间。根据 Facebook 的文档,Facebook 使用 ISO-8601 字符串来描述与 UTC 格式的偏移量的精确时间:

%Y-%m-%dT%H:%M:%S+OFFSET

在从 API 中提取时,一些事件以本地时间出现,例如示例 1,而其他事件以我的用户时间出现,例如示例 2(请注意,事件 1 和 2 的位置相同)。

示例 1) eid = 163113227202707, start_time = 2013-06-18T22:00:00-0700

示例 2) eid = 590809384285866, start_time = 2013-06-17T01:00:00-0300

我需要使用本地活动时间,包括夏令时。

我开始为大约 1500 个城市创建一个表格,格式如下:

city    timezone    dst offset
Abidjan GMT     +0000
Abuja   WAT     +0100
Accra   GMT     +0000
Adama   EAT     +0300
Addis Ababa EAT     +0300
Agadez  WAT     +0100
Agadir  WEST    DST +0100
Al Jizah    EET     +0200
Alexandria  EET     +0200
Algiers CET     +0100
Ali Sabieh  EAT     +0300
Antananarivo    EAT     +0300
Antsirabe   EAT     +0300
Arusha  EAT     +0300
Asmara  EAT     +0300
Bafatá  GMT     +0000
Bamako  GMT     +0000
Bambari WAT     +0100
Bamenda WAT     +0100
Bangui  WAT     +0100
Banjul  GMT     +0000
Bata    WAT     +0100
Beira   CAT     +0200
Benghazi    CST DST +0200
Benin City  WAT     +0100
Berbérati   WAT     +0100

但是,由于这是静态的,因此对夏令时没有帮助。

在阅读有关 pytz 的文档时,我不确定如何根据城市名称查询时区。这甚至可能吗?

本质上,我正在尝试创建以下伪代码:

start_time = 2013-06-17T01:00:00-0300

UTC_start_time = normalize_time_to_UTC(start_time)

offset = lookup_offset_given_city_and_UTC(city, UTC)

local_start_time(UTC_start_time, offset)

更新:

我首先通过解析字符串来根据 Facebook 提供的偏移量对时间进行标准化,如下所示:

def fql_local_time_to_utc(start_time):

    if len(fql_timestamp) < 20:
        return fql_timestamp

    else:
        timestamp = fql_timestamp[:19]
        sign = fql_timestamp[19]
        hours = fql_timestamp[20:22]
        minutes = fql_timestamp[22:24]
        offset = int(hours)+int(minutes)/60

        if sign =="+":
            offset = -offset

        timestamp_object = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S')
        utc_object = timestamp_object + datetime.timedelta(hours = offset)

        return utc_object 

接下来,我查找场地 ID 的 location_city 并尝试在上面的数据库中匹配它,我手动添加了一个名为“pytz_timezone_name”的列。通过连接查询找到相关时区后,我应用以下代码。

try:           
    tz = db.fetchone()["pytz_timezone_name"]
    tz_object = timezone(tz)
    local_event_time = timezone('UTC').localize(utc_time).astimezone(tz_object)
    local_time = local_event_time.strftime('%Y-%m-%dT%H:%M:%S%z')

except:

    local_time = start_time
4

1 回答 1

0

正如您所指出的,由于夏令时,您不能只拥有与偏移量相对应的城市表。此外,偏移量和时区规则一直在变化。你真的需要一个真正的时区数据库,比如pytz在 Python 中实现的IANA/Olson数据库。

从偏移量转换-07:00为时区是不可能的America/Denver。有许多时区共享相同的偏移量,一个时区可以有多个不同的偏移量,具体取决于具体的日期/时间。

Facebook 给了你一个date/time/offset,你可以得到精确的 UTC 时刻。但是其中的日期/时间部分应该已经针对事件的当地时间进行了调整。偏移量告诉您调整了多少。如果适用,此调整应考虑 DST。

但是,您说您为同一事件获得了两个不同的偏移量?这听起来很奇怪。您是否Events Timezone在您的 facebook api 中启用了该设置?这可以在 Facebook应用仪表板的高级设置中找到。

Facebook 活动时区设置

关于伪代码,是的,这一切都是可行的。也许您希望针对其他时区调整事件时间,那么这正是您要做的。请注意,它不仅仅是一个“城市”。这是 IANA 命名的时区标识符之一。 维基百科上的这篇文章很好地解释了它。

更新

关于您发布的更新,显示您的解决方案,我可以根据我在日期和时间问题方面的丰富经验提供以下反馈:

  • 除非您实际上正在编写一个专注于解析的库,否则几乎没有充分的理由将时间戳的一部分作为子字符串提取出来。您应该将其作为一个整体进行解析,并使用语言或框架提供的各种属性和功能。

  • 通常不需要使用字符串作为中间步骤,这可能是性能瓶颈。在某些语言中,由于文化/地区或本地时区设置,它可能会引入细微的错误。你从一个datetime对象开始,你想产生一个datetime对象,所以所有的操作都应该用datetime对象和相关的函数来完成。

  • Python 特别使用datetime. 您的代码以“aware”值开头,但是当您调用strptime. 由于输入值是“感知的”,因此您可能应该确保输出值也是如此。有关这方面的更多信息,请阅读这些文档的前几段。

  • 您一直说您正在查找城市以解决时区问题,但您根本没有提到这些数据的来源。您是否正在手动构建城市和时区表?这种方法可能在您最初的开发和测试期间有效,但随着时间的推移,您可能会发现它需要大量维护。世界上有很多城市。他们有时会更改名称,有时甚至会更改时区。您将不得不处理拼写错误、替代拼写、命名冲突等等。自己做这件事可能不是一个好主意。

  • 一个城市可能有多个时区的地方不止几个。如果您要尝试从某个位置解析时区,您将需要纬度和经度,以及其中一种机制

  • 仅供参考 - Python 没有自己的一组时区信息。pytz实现了一个由无数研究人员维护多年的公共时区数据库,通常被称为“Olson”数据库,以其创始人之一的名字命名。这目前由 IANA 协调,并在此处提供。您可以在Wikipedia上阅读更多信息,或者在StackOverflow 上的时区标签 wiki中阅读。

  • 这些数据一直在变化。当前版本是今年的第三个版本(2013c)。2012 年有 10 个版本。如果你想保持最新,你需要让你的 pytz 库保持最新

  • 我仍然认为你不需要这些。来自 Facebook 的事件时间应该已经是正确的本地时间,并显示该本地时间的偏移量。如果您看到应用了错误的偏移量,那么源数据可能一开始就是错误的。可能是活动地点不对。有一个表达,“垃圾进,垃圾出”。您可能希望更多地关注确保源数据正确,而不是尝试“修复”您认为来自 Facebook 的损坏输出。

于 2013-06-17T17:12:32.290 回答