【问题标题】:converting from local to utc timezone从本地时区转换为 UTC 时区
【发布时间】:2011-09-16 15:47:01
【问题描述】:

我正在尝试制作一个函数,该函数需要一个时间对象并将其转换为 UTC 时间。下面的代码似乎关闭了一小时。当我中午通过转换器运行时,我回到了 18:00:00。但是当我通过在线转换器运行相同的数据时,我得到了 17:00:00。

我在这里做错了什么?任何帮助将不胜感激。

import pytz, datetime

def convert_to_utc(time, tz):
    now_dt = datetime.datetime.utcnow()
    #get a date object
    date_dt = now_dt.date()
    #combine the current date object with our given time object
    dt = datetime.datetime.combine(date_dt, time)
    #get an timezone object for the source timezone
    src_tz = pytz.timezone(str(tz))
    #stamp the source datetime object with the src timezone 
    src_dt = dt.replace(tzinfo=src_tz)
    #get the offset from utc to given timezone
    offset = str(int(src_dt.strftime("%z"))).rstrip('0')
    #convert the source datetime object to
    utc_dt = src_dt.astimezone(pytz.utc)
    #return the converted time and the offset in integer format
    return (utc_dt.time(), int(offset))

time = datetime.datetime.strptime('12:00:00', "%H:%M:%S").time()
(TIME, offset) = convert_to_utc(time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")

**编辑**

这是更新(和功能)的代码,以防其他人需要帮助转换到 UTC。

感谢大家的帮助!

import pytz, datetime

def convert_to_utc(time, tz): #this returns the offset in int form as well
    now_dt = datetime.datetime.utcnow()
    #get a date object
    date_dt = now_dt.date()
    #combine the current date object with our given time object
    dt = datetime.datetime.combine(date_dt, time)
    #get an timezone object for the source timezone
    src_tz = pytz.timezone(str(tz))
    #stamp the source datetime object with the src timezone 
    src_dt = src_tz.localize(dt)
    #get the offset from utc to given timezone
    offset = str(int(src_dt.strftime("%z"))).rstrip('0')
    #convert the source datetime object to
    utc_dt = src_dt.astimezone(pytz.utc)
    #return the converted time and the offset in integer format
    return (utc_dt.time(), int(offset))

def convert_from_utc(time, tz):
    now_dt = datetime.datetime.now()
    date = now_dt.date()
    dt = datetime.datetime.combine(date, time)
    dest = pytz.timezone(str(tz))
    dt = dt.replace(tzinfo=pytz.utc)
    dest_dt = dt.astimezone(dest)
    return dest_dt.time()

time = datetime.datetime.strptime('12:00:00', "%H:%M:%S").time()
(TIME, offset) = convert_to_utc(time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")

utc_time = datetime.datetime.strptime('17:00:00', "%H:%M:%S").time()
TIME = convert_from_utc(utc_time, 'America/Chicago')
print TIME.strftime("%H:%M:%S")

【问题讨论】:

  • CST 是 UTC +6,但是,由于夏令时,芝加哥目前比 UTC 晚 5 小时。我怀疑这是你的问题。
  • 但我通过世界时间服务器而不是 CST 运行“美国/芝加哥”
  • utc 和 tz 不一定具有相同的日期,因此 now_dt.date() 可能会延迟一天。如果恰好是 DST 过渡日,则 convert_to_utc() 的返回值可能会相差一个小时。
  • 如果dt 处于夏令时转换期间,src_tz.localize(dt) 无法在没有 is_dst 参数的情况下明确获得结果。
  • convert_from_utc() 中的日期也可能有误。为什么是.now() 而不是.utcnow()

标签: python timezone pytz


【解决方案1】:

改变

src_dt = dt.replace(tzinfo=src_tz)

src_dt = src_tz.localize(dt)

使用localize 会调整夏令时,而replace 不会。 请参阅标题为“本地化时间和日期算术”的部分in the docs

【讨论】:

    【解决方案2】:

    将给定时区的时间转换为 UTC 时间:

    from datetime import datetime
    import pytz
    
    def convert_to_utc(time, tzname, date=None, is_dst=None):
        tz = pytz.timezone(tzname)
        if date is None: # use date from current local time in tz
            date = datetime.now(tz).date()
    
        dt = tz.localize(datetime.combine(date, time), is_dst=is_dst)
        return dt.astimezone(pytz.utc).time(), dt.utcoffset().total_seconds()
    

    如果is_dstNone,它会在本地时间不明确时引发异常。

    将 UTC 时间转换为给定时区的本地时间:

    def convert_from_utc(time, tzname, date=None):
        tz = pytz.timezone(tzname)
        if date is None: # use date from current time in utc
            date = datetime.utcnow().date()
        dt = datetime.combine(date, time).replace(tzinfo=pytz.utc)
        return tz.normalize(dt.astimezone(tz)).time()
    

    示例:

    time = datetime.strptime('12:00:00', "%H:%M:%S").time()
    utc_time, offset = convert_to_utc(time, 'America/Chicago')
    print utc_time.strftime("%H:%M:%S"), offset # -> 17:00:00 -18000.0
    
    utc_time = datetime.strptime('17:00:00', "%H:%M:%S").time()
    time = convert_from_utc(utc_time, 'America/Chicago')
    print time.strftime("%H:%M:%S") # -> 12:00:00
    

    一般来说,最好使用完整的 datetime 对象以避免对正确日期的歧义,即传递和返回 datetime 对象。

    【讨论】:

      【解决方案3】:

      通过对日期时间使用replace 方法,您不允许针对夏令时调整时区。尝试使用pytz documentation 中记录的方法之一:

      src_dt = src_tz.localize(dt)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-12
        • 1970-01-01
        • 2019-05-31
        • 2021-04-20
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多