使用Python将GMT从CSV文件转换为EST

时间:2013-11-12 01:30:33

标签: python datetime csv

我有一个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

感谢您的帮助!!

2 个答案:

答案 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会为您处理边缘情况,例如日历更改日期。当您减去受夏令时或闰秒变化影响的时间戳时,它甚至应该做正确的事情。

编辑:此处的代码使用calendartime但实际上并未使用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.")