我在代表 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
...
有人可以帮我吗?谢谢
我知道在时区之间转换的最简单、最可靠的方法是使用第三方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
. 这个想法是转换 datetime --> timetuple --> timestamp --> UTC datetime。转换链完成
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),这里是如何将表示本地时间的 datetime 对象转换为表示 GMT 时间的 datetime 对象,反之亦然:
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)
每条记录的伪代码:
制作一个时间戳字符串: field[0].strip() + " " + field[1].strip()
使用 datetime.datetime.strptime() 将其转换为 datetime.datetime 实例
将 timedelta 例如 timedelta(hours=-4) 添加到您的时间戳
使用 timestamp.strftime() 为输出生成您想要的任何字符串表示形式。
对于时间字段为空的情况:如果这意味着 0:0:0,请修改上述内容以适应。如果它的意思是“时间未知”,你需要做其他事情......
假设我们在美国/东部时间有一个日期时间字符串为“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
如果没有关联的时间,时区无关紧要......日期也不能转换为不同的时区。另一栏是否有相关时间?
编辑:好的,现在有时间,我会让蟒蛇大师接管。;]
我必须在 Python 中创建一个自定义函数来将 EST 转换为 GMT,这是我编写的代码:
#convert est time to gmt. Make sure you assign the current EST values
#to the following variables
est_year
est_month
est_day
est_hour
est_min
gmt_year = est_year
gmt_month = est_month
gmt_day = est_day
gmt_hour = est_hour + 5 #gmt is ahead by 5 hrs
gmt_min = est_min
if gmt_hour > 23:
gmt_hour = gmt_hour - 23
gmt_day = est_day + 1
days_in_month = calendar.monthrange(est_year,est_month)[1] #in case the no days becomes 32..
if gmt_day > days_in_month:
gmt_day = 1
gmt_month = gmt_month + 1
if gmt_month > 12:
gmt_month = 1
gmt_year = gmt_year + 1
gmttime = datetime.datetime(gmt_year, gmt_month, gmt_day, gmt_hour, gmt_min, 0)
我没有添加对 EDT 的支持。现在是二月,正在遵循美国东部标准时间。欢迎任何更改或更正!
你可以pandas.DataFrame.tz_convert()
这样使用:
import pandas as pd
from datetime import datetime
df = pd.read_csv("your_data_file_path.csv", index_col=False, engine='python')
df['Date'] = pd.to_datetime(df['Date'])
df['Date'] = df['Date'].dt.tz_localize('US/Eastern').dt.tz_convert('UTC')
df['Date'] = df['Date'].apply(lambda x: datetime.replace(x, tzinfo=None))
最后一行所做的是从 datetime 对象中删除时区信息,因此您可以仅使用日期和时间进行操作(不用担心,这不会再次更改时区,它只是从时间戳字符串中删除它)。