1

我有一个包含日期列和时间列的 CSV 文件。时间列是 GMT(24 小时格式),我需要将其转换为 EST。因为是夏令时,现在东海岸的时差是-5小时。我需要一种方法来读取 CSV 文件并从列中的所有时间中减去 5 小时。我最大的问题是许多转换将持续两天。例如,“Thu Nov 7,0:30”将转换为“Thu Nov 6,19:30”。如果日期和时间转换为前一天,我需要更改 CSV 中的日期。这是我正在使用的数据示例:


日期、时间
11 月 6 日周三
0:01 11 月 6 日周三 0:30 11 月 6 日
周三 8:00
11 月 6 日周三 13:30 11 月 7 日
周四 0:30 11 月 7 日 周四
2:00
:00 11 月 7

星期四 15:30 11 月 7 日星期四 20:00
11 月 8 日星期五 0:30 11 月 8 日星期五 2:30 11 月 8 日星期五6:45 11 月 8 日
星期五 9:30 11 月 8 日 13 日 星期五: 30 周五 11 月 8 日 17:00 11 月 9 日 周六 11 月 30 日 11 月 9 日周六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 月 6 日星期四
19:30 11 月 6 日
星期四 21:00 11 月 7 日
星期四:00
11 月 7 日
星期四
10:30 11 月 7 日星期四 15:00 11 月 7 日星期五 19:30 11 月 7 日
星期五 21:30 11 月 8 日星期五 1:45 11 月 8 日星期五 4:30 11 月 8

星期五
: 30
周五 11 月 8 日 12:00
11 月 8 日 周六 20:30 11 月 9 日
周六 0:30 11 月 10 日周日 16:45 11 月 10日
18:50

我有一些代码来确定 DST 的状态(-4 小时或 -5 小时)。我需要帮助阅读 CSV 文件,遍历时间列,减去正确的小时数,并在时间/日期更改为前一天时更改任何相应的日期。我正在使用 Python 2.7.5

谢谢您的帮助!!

4

2 回答 2

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)
于 2013-11-12T01:46:38.877 回答
-1

编辑:我认为pytz答案比这个更干净,但我将把它留在这里以展示一般情况。如果您发现时钟快了 23 分钟或其他什么,此技术可以让您更正时间戳。但pytz看起来这是处理时区转换的最简单方法。

用于datetime将日期字符串转换为单个数字(时间戳值,自“纪元”以来的秒数)。通过转换为秒来减去所需的时间(5 小时 == 5 * 60 * 60)。然后用于datetime将数字转换回时间戳字符串。

datetime将为您处理边缘情况,例如日历日期更改。当您减去会受到夏令时变化或闰秒等影响的时间戳时,它甚至应该做正确的事情。

编辑:这是使用但实际上并未使用calendar的代码。我没时间看这个......在我的测试中,它打印了“11 月 6 日”而不是“11 月 6 日”,但这与你想要的很接近。timedatetime

在将时间戳传递给此函数之前,从时间戳周围去除空格。

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.")
于 2013-11-12T01:35:31.940 回答