使用datetime和timezone时代码问题

时间:2017-08-31 23:40:44

标签: python date datetime pytz

我有一个名为'entries'的字符串列表。每个条目都包含一个日期和时间,格式如下:'Mon Jun 15 17:52:03 2015'

我正在使用正则表达式解析每个条目的日期/时间,然后我需要将它们放入python的日期时间格式并将时区更改为UTC(本地时间+4小时)。这是我的代码:

from datetime import datetime
import pytz

local = pytz.timezone("Etc/GMT+4")
localdate = [None]*len(entries)
local_dt = [None]*len(entries)
utc_dt = [None]*len(entries)
utdate = [None]*len(entries)

for i in range(len(entries)):
    localdate[i] = datetime.strptime(re.search(r'\w{3}\s*?\w{3}\s*?\d{1,2}\s*?
\d{1,2}:\d{2}:\d{2}\s*?\d{4}', entries[i]).group(0), "%c")
    local_dt[i] = local.localize(localdate[i], is_dst=None)
    utc_dt[i] = local_dt[i].astimezone(pytz.utc)
    utdate[i] = utc_dt[i].strftime("%c")

utdate = map(str, utdate)
print utdate

如果我浏览并打印每一步,它似乎能够逐行工作,但是一旦到达最后一步,它将恢复为日期/时间的原始格式,而不是python日期时间格式' yyyy-mm-dd hh:mm:ss'。谁知道什么是错的?

1 个答案:

答案 0 :(得分:1)

TL;博士

您将datetime对象格式化为utdate[i] = utc_dt[i].strftime("%c")的字符串。 %c代码formats the date according to the system's localization settings,而不是您期望的格式。

datetime对象的标准字符串表示形式将生成您正在寻找的格式 - 您可以从str(some_datetime)print(some_datetime)获取字符串以将其打印到控制台。

时区

众所周知,这很难跟踪,但您可能需要仔细检查您正在使用的时区。因此,您的代码将花费一个输入时间并提供4小时前的输出时间。如果我理解正确,你会反过来看。您应该知道"Etc" timezones are labelled oppositely for weird reasons,并且您可能想要更改使用的时区。这是一个不同的问题,但使用基于位置的时区而不是UTC偏移可能是DST支持等事情的好主意。

改进

您可以通过一些更改来简化和澄清您尝试执行的操作。它使它更多" Pythonic"同样。

input_format = '%a %b %d %H:%M:%S %Y' # Change 1
converted_entries = [] # Change 2

for entry in entries: # Change 3
    local_date = datetime.strptime(entry, input_format) # Change 1 (continued)
    # Change 4
    localized_date = local.localize(local_date)
    utc_date = localized_date.astimezone(pytz.utc)
    converted_entries.append(utc_date)

utdate = map(str, converted_entries)
print utdate

更改

  1. 使用strftime/strptime formatterstrftimestrptime旨在解析字符串,通常不需要正则表达式来处理它们。输出格式也是如此 - 如果需要特定格式而不提供datetime.isoformat等内置方法,请使用格式化程序。

  2. 在Python中,没有必要提前将列表初始化(或使用None)。 list_var = []list_var = list()将为您提供一个可按需扩展的空列表。

  3. 通常,迭代列表是最好也是最简单的,而不是跳过箍来获得循环计数器。它更具可读性,最终难以记住。

    • 如果您确实需要计数器,请使用enumerate例如for i, entry in enumerate(entries):
  4. 使用范围变量。 localdatelocaldt等临时值只能保留在for循环中。从技术上讲,它浪费了内存,但更重要的是它使代码更简单,更封装。

  5. 如果稍后需要这些值,请执行我对converted_entries列表所做的操作。在循环外部初始化它,然后每次都将值附加到列表中。

  6. 无需计数器变量:

    localized_dates = []
    for # omitted ...
        localized_date = local.localize(local_date)
        localized_dates.append(localized_date)
    

    我希望这对你有所帮助。 Python的美妙之处在于它可以非常简单,所以只需拥抱它