如何将EST/EDT转换为GMT?

9 投票
6 回答
16801 浏览
提问于 2025-04-16 14:45

我有一些记录在一个列里面,这些记录表示的是东部标准时间(EST)或者东部夏令时间(EDT)。我需要把这些时间转换成格林威治标准时间(GMT)。这些时间的格式是:

10/1/2010   0:0:0
10/1/2010   0:6:0
...
10/1/2010   23:54:0
...
10/3/2010   0:0:0
...

有人能帮我一下吗?谢谢!

6 个回答

2

假设我们有一个日期时间字符串,比如“2019-04-09T23:59:55ET”,这是美国东部时间。下面是一个将这个字符串转换为协调世界时(UTC)的函数:

from datetime import datetime
import pytz

eastern = pytz.timezone('US/Eastern')

def convent_est_to_utc(datetime_str):
    dt = datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%SET')
    return dt.replace(tzinfo=eastern).astimezone(pytz.utc)

# testing
convent_est_to_utc("2019-04-09T23:59:55ET")

# The result: 2019-04-10 04:55:55+00:00

2

每条记录的伪代码:

先创建一个时间戳字符串:把字段[0]去掉前后空格后加上一个空格,再加上字段[1]去掉前后空格后的内容。

接着,用datetime.datetime.strptime()这个方法把这个字符串转换成一个日期时间的实例。

然后,给你的时间戳加上一个时间差,比如说timedelta(hours=-4),这样可以调整时间。

最后,使用timestamp.strftime()来生成你想要的字符串格式作为输出。

如果时间字段是空的:如果这表示的是0:0:0,就需要调整上面的步骤。如果表示的是“时间未知”,那你就得另想办法了……

18

我知道最简单、最可靠的方式来转换时区,就是使用一个叫做 pytz 的第三方模块:

import pytz
import datetime as dt

utc=pytz.utc
eastern=pytz.timezone('US/Eastern')
fmt='%Y-%m-%d %H:%M:%S %Z%z'

text='''\
10/1/2010   0:0:0
10/1/2010   0:6:0
10/1/2010   23:54:0
10/3/2010   0:0:0
'''

for datestring in text.splitlines():
    date=dt.datetime.strptime(datestring,"%m/%d/%Y %H:%M:%S")
    date_eastern=eastern.localize(date,is_dst=None)
    date_utc=date_eastern.astimezone(utc)
    print(date_utc.strftime(fmt))

这个方法会得到:

2010-10-01 04:00:00 UTC+0000
2010-10-01 04:06:00 UTC+0000
2010-10-02 03:54:00 UTC+0000
2010-10-03 04:00:00 UTC+0000

不过要注意,你的数据并没有说明这个时间是东部标准时间(EST)还是东部夏令时间(EDT)。有些时间在没有明确说明是EST还是EDT的情况下会变得模糊。例如,'10/27/2002 1:30:00' 这个时间就不明确:

>>> eastern.localize(datetime(2002, 10, 27, 1, 30, 00), is_dst=None)
AmbiguousTimeError: 2002-10-27 01:30:00

因为这个时间由于夏令时的原因出现了两次。此外,有些时间,比如 2002-04-07 02:30:00,是不存在的。想了解这些问题以及处理本地时间时可能出现的更奇怪的问题,可以查看 这个链接

如果你愿意忽略这些复杂的边缘情况,并且你的机器设置在本地时区(例如 EST/EDT),那么有一种方法可以在本地时区和 UTC 时区之间转换,而不需要安装 pytz。这个方法的思路是将日期时间转换为时间元组,再转换为时间戳,最后转换为 UTC 日期时间。这个转换链条是通过以下方式完成的:

dt.datetime.utcfromtimestamp(time.mktime(date.timetuple()))

例如:

import time
import datetime as dt
import pytz

utc=pytz.utc
eastern=pytz.timezone('US/Eastern')
fmt='%Y-%m-%d %H:%M:%S %Z%z'

text='''\
10/1/2010   0:0:0
10/1/2010   0:6:0
10/1/2010   23:54:0
10/3/2010   0:0:0
3/13/2011   1:55:0
3/13/2011   3:00:0
'''
for datestring in text.splitlines():
    date=dt.datetime.strptime(datestring,"%m/%d/%Y %H:%M:%S")
    date_est=eastern.localize(date,is_dst=None)
    date_utc=date_est.astimezone(utc)
    date_utc2=dt.datetime.utcfromtimestamp(time.mktime(date.timetuple()))
    print('{d} --> {d_utc}    {d_utc2}'.format(
        d=date.strftime(fmt),
        d_utc=date_utc.strftime(fmt),
        d_utc2=date_utc2.strftime(fmt),
        ))
    assert date_utc.hour == date_utc2.hour

得到的结果是

2010-10-01 00:00:00 EDT-0400 --> 2010-10-01 04:00:00 UTC+0000    2010-10-01 04:00:00 
2010-10-01 00:06:00 EDT-0400 --> 2010-10-01 04:06:00 UTC+0000    2010-10-01 04:06:00 
2010-10-01 23:54:00 EDT-0400 --> 2010-10-02 03:54:00 UTC+0000    2010-10-02 03:54:00 
2010-10-03 00:00:00 EDT-0400 --> 2010-10-03 04:00:00 UTC+0000    2010-10-03 04:00:00 
2011-03-13 01:55:00 EST-0500 --> 2011-03-13 06:55:00 UTC+0000    2011-03-13 06:55:00 
2011-03-13 03:00:00 EDT-0400 --> 2011-03-13 07:00:00 UTC+0000    2011-03-13 07:00:00 

上面测试的最后两个日期显示,即使在接近 EST 和 EDT 切换的时间,转换也能正确进行。


总之,使用这种替代方法(不使用 pytz),下面是如何将表示本地时间的日期时间对象转换为表示 GMT 时间的日期时间对象,以及反向转换的方法:

In [83]: import datetime as dt
In [84]: import time
In [85]: import calendar

In [86]: date=dt.datetime(2010,12,1,0,0,0)    
In [87]: date
Out[87]: datetime.datetime(2010, 12, 1, 0, 0)

In [88]: date_utc=dt.datetime.utcfromtimestamp(time.mktime(date.timetuple()))    
In [89]: date_utc
Out[89]: datetime.datetime(2010, 12, 1, 5, 0)

In [90]: date_local=dt.datetime.fromtimestamp(calendar.timegm(date_utc.timetuple()))    
In [91]: date_local
Out[91]: datetime.datetime(2010, 12, 1, 0, 0)

撰写回答