【问题标题】:Converting correctly between tz unaware time, UTC and working with timezones in python在 tz 不知道时间、UTC 和在 python 中使用时区之间正确转换
【发布时间】:2011-09-27 00:20:26
【问题描述】:

我有一个格式为“20111014T090000”的字符串以及相关的时区 ID (TZID=America/Los_Angeles),我想要 使用适当的偏移量将其转换为 UTC 时间(以秒为单位)。

问题似乎是我的输出时间减少了 1 小时(它在 PST 中应该是 PDT)并且我正在使用 pytz 来帮助处理 timezo

import pytz

def convert_to_utc(date_time)
    # date_time set to '2011-10-14 09:00:00' and is initially unaware of timezone information

    timezone_id = 'America/Los_Angeles'
    tz = pytz.timezone(timezone_id);

    # attach the timezone
    date_time = date_time.replace(tzinfo=tz);

    print("replaced: %s" % date_time);                                                                          
    # this makes date_time to be: 2011-10-14 09:00:00-08:00
    # even though the offset should be -7 at the present time

    print("tzname: %s" % date_time.tzname());
    # tzname reports PST when it should be PDT

    print("timetz: %s" % date_time.timetz());
    # timetz: 09:00:00-08:00 - expecting offset -7

    date_time_ms = int(time.mktime(date_time.utctimetuple())); 
    # returns '1318611600' which is 
    # GMT: Fri, 14 Oct 2011 17:00:00 GMT
    # Local: Fri Oct 14 2011 10:00:00 GMT-7

    # when expecting: '1318608000' seconds, which is
    # GMT: Fri, 14 Oct 2011 16:00:00 GMT
    # Local: Fri Oct 14 2011 9:00:00 GMT-7 -- expected value

如何根据时区 ID 获得正确的偏移量?

【问题讨论】:

  • 您需要致电date_time.localize。这是这里完全缺少的唯一基本成分。

标签: python pytz


【解决方案1】:

下面的sn-p会做你想做的事

def convert(dte, fromZone, toZone):
    fromZone, toZone = pytz.timezone(fromZone), pytz.timezone(toZone)
    return fromZone.localize(dte, is_dst=True).astimezone(toZone)

这里的关键部分是将is_dst 传递给localize 方法。

【讨论】:

  • 根据文档,似乎 is_dst 标志可能无法解释并提供预期值: >>> dt = datetime(2002, 10, 27, 1, 30, 0) >>> dt1 = eastern.localize(dt, is_dst=True) >>> dt1.strftime(fmt) '2002-10-27 01:30:00 EDT-0400' >>> dt2 = eastern.localize(dt, is_dst=False ) >>> dt2.strftime(fmt) '2002-10-27 01:30:00 EST-0500'
  • is_dst 参数是可选的,除非在时间不明确的情况下(即在“回退”期间,一天中的同一小时在本地时区出现两次)。其余时间转换将在没有它的情况下工作。该参数告诉pytz 夏令时是否对您提供的datetime 对象有效。
【解决方案2】:

simple-date 是为了进行这样的简单转换而编写的(为此需要 0.2.1 或更高版本):

>>> from simpledate import *
>>> SimpleDate('20111014T090000', tz='America/Los_Angeles').timestamp
1318608000.0

【讨论】:

    【解决方案3】:

    如果(暂时)允许在您的程序中更改全球时区,您也可以这样做:

    os.environ['TZ'] = 'America/Los_Angeles'
    t = [2011, 10, 14, 9, 0, 0, 0, 0, -1]
    return time.mktime(time.struct_time(t))
    

    返回预期的 1318608000.0。

    【讨论】:

      【解决方案4】:

      将给定的字符串转换为简单的日期时间对象:

      >>> from datetime import datetime
      >>> naive_dt = datetime.strptime('20111014T090000', '%Y%m%dT%H%M%S')
      >>> naive_dt
      datetime.datetime(2011, 10, 14, 9, 0)
      

      附加时区(使其成为可感知的日期时间对象):

      >>> import pytz
      >>> tz = pytz.timezone('America/Los_Angeles')
      >>> local_dt = tz.localize(naive_dt, is_dst=None)
      >>> print(local_dt.strftime("%Y-%m-%d %H:%M:%S %Z%z"))
      2011-10-14 09:00:00 PDT-0700
      

      注意:is_dst=None 用于为不存在或不明确的当地时间引发异常。

      从感知的日期时间对象获取 POSIX 时间戳:

      >>> (local_dt - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
      1318608000.0
      

      您问题中的主要问题是:

      1. 你替换tzinfo属性,tz.localize应该被替换
      2. mktime() 适用于本地时间(您的计算机时区),而不是 UTC。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-01
        • 2022-11-18
        • 2021-12-07
        • 2011-12-07
        相关资源
        最近更新 更多