我有一个CSV文件,其中包含日期列和时间列。时间列是GMT(24小时格式),我需要将其转换为EST。因为它是夏令时,所以现在东海岸的时差为-5小时。我需要一种方法来读取CSV文件,并从列中的所有时间中减去5小时。我最大的问题是许多转换将涵盖两天。例如,“Thu Nov 7,0:30”将转换为“Thu Nov 6,19:30”。如果日期和时间转换为前一天,我需要更改CSV中的日期。以下是我正在使用的数据示例:
日期,时间
11月6日星期三,01:01
11月6日星期三,30:30
11月6日星期三,8:00
周三11月3日,13:30
星期四11月7日,30:30
星期四11月7日,2:00
星期四11月7日5:00
星期四11月5日,15:30
星期四11月7日,20:00
星期五8月8日,30:30
星期五11月8日,2:30
星期五8月6日,6:45
星期五8月9日至9日
星期五11,13:30
星期五11月7日,7:00
星期六11月9日,1:30
星期六9月5日,5:30
周日11月10日,21:45
周日11月10,23:50
以下是我希望数据在-5小时转换后的效果:
日期,时间
星期三11月5日,19:01
11月6日星期三,19:30
11月6日星期三,3:00
11月6日星期三,8:30
星期四11月9日,19:30
星期四11月1日,21:00
星期四,11月7日,0:00
星期四11月7日10:30
星期四11月5日,15:00
星期五,11:9:30
星期五11月1日,21:30
星期五8月8日,1:45
星期五11月8日,4:30
星期五8月8日,8:30
11月8日星期五,星期五
星期六11月8日,20:30
11月9日上午9点30分
太阳11月10日,16:45
周日11月10日,18:50
我有一些代码来确定DST的状态(-4小时或-5小时)。我需要帮助阅读CSV文件,迭代时间列,减去正确的小时数,并在时间/日期更改为前一天时更改任何相应的日期。我正在使用Python 2.7.5
感谢您的帮助!!
答案 0 :(得分:2)
您需要使用datetime和pytz。这些是您应该遵循的步骤:
首先,显然,解析csv并将每一行加载到一个天真的日期时间对象(没有时区)。
其次,让datetime对象知道时区:
src_tz = pytz.timezone('GMT')
dt = src_tz.localize(dt)
然后将它们转换为您想要的时区:
dst_tz = pytz.timezone('EST')
dt = dt.astimezone(dst_tz)
答案 1 :(得分:-1)
pytz
答案比这个答案更清晰,但我会在这里留下来说明一般情况。如果你发现时钟快了23分钟或者某种东西,这种技术可以让你纠正时间戳。但pytz
似乎是处理时区转换的最简单方法。
使用datetime
将日期字符串转换为单个数字(时间戳值,自“epoch”以来的秒数)。通过转换为秒(5小时== 5 * 60 * 60)减去所需的时间。然后使用datetime
将数字转换回时间戳字符串。
datetime
会为您处理边缘情况,例如日历更改日期。当您减去受夏令时或闰秒变化影响的时间戳时,它甚至应该做正确的事情。
编辑:此处的代码使用calendar
和time
但实际上并未使用datetime
。我没时间看这个...在我的测试中它打印出“Nov 6”而不是“Nov 06”,但是这很接近你想要的。
在将时间戳传递给此函数之前从时间戳周围删除空格。
import calendar
import time
def convert_ts(timestamp, change):
temp = time.strptime(timestamp, "%a %b %d,%H:%M")
t = calendar.timegm(temp)
t += change
temp = time.gmtime(t)
return time.strftime("%a %b %0d,%H:%M", temp)
编辑:好的,这是一个实现上述功能的完整程序,包括测试用例。当我测试上面的内容时,我发现工作日不对,我认为这是因为时间戳不包括年份。所以,我添加了一个default_year
参数。
您可以编写代码来计算当前年份,如果有人要求,我会补充说明。
s = """\
Wed Nov 6,0:01
Wed Nov 6,0:30
Wed Nov 6,8:00
Wed Nov 6,13:30
Thu Nov 7,0:30
Thu Nov 7,2:00
Thu Nov 7,5:00
Thu Nov 7,15:30
Thu Nov 7,20:00
Fri Nov 8,0:30
Fri Nov 8,2:30
Fri Nov 8,6:45
Fri Nov 8,9:30
Fri Nov 8,13:30
Fri Nov 8,17:00
Sat Nov 9,1:30
Sat Nov 9,5:30
Sun Nov 10,21:45
Sun Nov 10,23:50"""
data = [line.strip() for line in s.split('\n')]
s = """\
Tue Nov 5,19:01
Tue Nov 5,19:30
Wed Nov 6,3:00
Wed Nov 6,8:30
Wed Nov 6,19:30
Wed Nov 6,21:00
Thu Nov 7,0:00
Thu Nov 7,10:30
Thu Nov 7,15:00
Thu Nov 7,19:30
Thu Nov 7,21:30
Fri Nov 8,1:45
Fri Nov 8,4:30
Fri Nov 8,8:30
Fri Nov 8,12:00
Fri Nov 8,20:30
Sat Nov 9,0:30
Sun Nov 10,16:45
Sun Nov 10,18:50"""
correct = [line.strip() for line in s.split('\n')]
import calendar
import time
import re
pat_lead0 = re.compile(r'([ ,])0(\d)')
def convert_ts(timestamp, default_year, change):
temp = time.strptime(timestamp + " %04d" % default_year, "%a %b %d,%H:%M %Y")
t = calendar.timegm(temp)
t += change
temp = time.gmtime(t)
s = time.strftime("%a %b %0d,%H:%M", temp)
s = re.sub(pat_lead0, r'\1\2', s)
return s
offset = -5 * 60 * 60 # seconds in five hours
for s, k in zip(data, correct):
result = convert_ts(s, 2013, offset)
if result != k:
print("result: '{}' correct: '{}'".format(result, k))
print("Done.")