Facebook事件start_time有时在用​​户时间,其他人在本地事件时间

时间:2013-06-17 15:05:18

标签: python facebook-graph-api datetime timezone pytz

我正在尝试转换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 

接下来,我查找venue_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

1 个答案:

答案 0 :(得分:0)

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

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

Facebook为您提供了date/time/offset,您可以获得精确的UTC时刻。但是应该已经根据事件的当地时间调整了日期/时间部分。偏移量告诉您调整了多少。如果适用,此调整应考虑DST。

但是,你说你在同一场比赛中得到了两个不同的补偿?这听起来很奇怪。您是否在facebook api中启用了Events Timezone设置?这可以在您的Facebook app dashboard的高级设置中找到。

Facebook Events Timezone setting

关于伪代码,是的,这一切都是可行的。也许您希望将事件时间调整为其他时区,这正是您要做的。请注意,这不仅仅是一个“城市”。这是IANA命名的时区标识符之一。 This article on Wikipedia很好地解释了这一点。

更新

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

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

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

  • Python特别使用datetime的“天真”或“意识”值的概念。您的代码以“感知”值开头,但是当您致电strptime时,您正构建一个“天真”的代码。由于输入值是“察觉”,您应该确保输出值也是如此。有关详细信息,请阅读these docs的前几段。

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

  • 超过a few places where a city might have multiple time zones。如果您要尝试从某个位置解析时区,则需要经度和纬度,以及these mechanisms之一。

  • 仅供参考 - Python没有自己的时区信息集。 pytz实现了一个公共时区数据库,该数据库已被无数研究人员(通常称为“Olson”数据库)维护了多年,该数据库的创始人之一。目前,这是由IANA协调的,并且已归属here。您可以在Wikipedia上或在StackOverflow上的timezone tag wiki中阅读更多内容。

  • 此数据一直在变化。目前的发布是今年的第三次发布(2013c)。 2012年,有10个版本。如果您想保持最新状态,则需要keep your pytz library up to date

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