Skip to main content
 首页 » 编程设计

python将本地时间的字符串转换为UTC纪元时间戳

2025年05月04日49oomusou

我有 YMD hms 格式的字符串,其中的时区被去除了。但我知道他们在东部时间,夏令时。

我正在尝试将它们转换为 UTC 时间的纪元时间戳。

我写了下面的函数:

def ymdhms_timezone_dst_to_epoch(input_str,  tz="US/Eastern"): 
    print(input_str) 
    dt = datetime.datetime.fromtimestamp(time.mktime(time.strptime(input_str,'%Y-%m-%d %H:%M:%S'))) 
    local_dt = pytz.timezone(tz).localize(dt) 
    print(local_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z')) 
    utc_dt = local_dt.astimezone(pytz.utc) 
    print(utc_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))     
    e = int(utc_dt.strftime("%s")) 
    print(e) 
    return e 
 
Given string `2015-04-20 21:12:07` this prints: 
 
    2015-04-20 21:12:07 
    2015-04-20 21:12:07 EDT-0400 #<- so far so good? 
    2015-04-21 01:12:07 UTC+0000 #<- so far so good? 
    1429596727 

根据纪元时间戳看起来没问题。但是http://www.epochconverter.com/epoch/timezones.php?epoch=1429596727说应该毛到 格林威治标准时间 2015 年 4 月 21 日 06:12:07 UTC。

怎么了?

请您参考如下方法:

I have strings in YMD hms format that had the timezone stripped. But I know they are in Eastern time with daylight savings time.

一种可移植的方式是使用pytz:

#!/usr/bin/env python 
from datetime import datetime 
import pytz # $ pip install pytz 
 
naive_dt = datetime.strptime('2015-04-20 21:12:07', '%Y-%m-%d %H:%M:%S') 
tz = pytz.timezone('US/Eastern') 
eastern_dt = tz.normalize(tz.localize(naive_dt)) 
print(eastern_dt) 
# -> 2015-04-20 21:12:07-04:00 

I am trying to convert them into epoch timestamps for UTC time.

timestamp = (eastern_dt - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds() 
# -> 1429578727.0 

参见 Converting datetime.date to UTC timestamp in Python .


您的代码中存在多个问题:

  • time.mktime() 可能会为不明确的输入时间返回错误结果(50% 的几率),例如,在秋季的“回退”DST 转换期间

    <
  • 如果
  • time.mktime() 和 datetime.fromtimestamp() 无法访问历史时区数据库,则它们可能会在过去/ future 日期失败系统(尤其是 Windows)

  • localize(dt) 可能会为不明确或不存在的时间返回错误结果,即在 DST 转换期间。如果您知道时间对应于夏令时,则使用 is_dst=True。 tz.normalize() 是必要的,以调整输入中可能不存在的时间

  • utc_dt.strftime("%s") is not portable and it does not respect tzinfo object .它将输入解释为本地时间,即,除非您的本地时区是 UTC,否则它会返回错误的结果。


Can I just always set is_dst=True?

如果您不介意在模棱两可或不存在的时间获得不精确的结果,例如,在美国/纽约时区的秋季有 DST 转换:

>>> from datetime import datetime 
>>> import pytz # $ pip install pytz 
>>> tz = pytz.timezone('America/New_York') 
>>> ambiguous_time = datetime(2015, 11, 1, 1, 30) 
>>> time_fmt = '%Y-%m-%d %H:%M:%S%z (%Z)' 
>>> tz.localize(ambiguous_time).strftime(time_fmt) 
'2015-11-01 01:30:00-0500 (EST)' 
>>> tz.localize(ambiguous_time, is_dst=False).strftime(time_fmt) # same 
'2015-11-01 01:30:00-0500 (EST)' 
>>> tz.localize(ambiguous_time, is_dst=True).strftime(time_fmt) # different 
'2015-11-01 01:30:00-0400 (EDT)' 
>>> tz.localize(ambiguous_time, is_dst=None).strftime(time_fmt)  
Traceback (most recent call last): 
... 
pytz.exceptions.AmbiguousTimeError: 2015-11-01 01:30:00 

时钟倒转at 2a.m. on the first Sunday in November :

is_dst 消歧标志可以有三个值:

  • False -- 默认,假定冬令时
  • True -- 假设夏令时
  • None -- 为不明确/不存在的时间引发异常。

is_dst 值对于现有的唯一本地时间将被忽略。

这是来自 PEP 0495 -- Local Time Disambiguation 的情节说明 DST 转换:

本地时间在折页中重复两次(夏令时 - 折页前,冬令时 - 折页后)。

为了能够自动消除本地时间的歧义,您需要一些额外的信息,例如,如果您阅读了一系列本地时间,那么如果您知道它们已排序可能会有所帮助:Parsing of Ordered Timestamps in Local Time (to UTC) While Observing Daylight Saving Time .