我正在尝试转换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
答案 0 :(得分:0)
正如您所指出的,由于夏令时,您不能仅拥有与偏移相对应的城市表。此外,抵消和时区规则一直在变化。您确实需要一个真正的时区数据库,例如IANA/Olson在Python中实现的pytz数据库。
无法将-07:00
等偏移转换为America/Denver
等时区。有许多时区共享相同的偏移量,单个时区可以有多个不同的偏移量,具体取决于具体的日期/时间。
Facebook为您提供了date/time/offset,您可以获得精确的UTC时刻。但是应该已经根据事件的当地时间调整了日期/时间部分。偏移量告诉您调整了多少。如果适用,此调整应考虑DST。
但是,你说你在同一场比赛中得到了两个不同的补偿?这听起来很奇怪。您是否在facebook api中启用了Events Timezone
设置?这可以在您的Facebook app dashboard的高级设置中找到。
关于伪代码,是的,这一切都是可行的。也许您希望将事件时间调整为其他时区,这正是您要做的。请注意,这不仅仅是一个“城市”。这是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的损坏输出。