【问题标题】:Specify which timezone a datetime is in, in python在python中指定日期时间所在的时区
【发布时间】:2014-05-17 09:35:14
【问题描述】:

我有一个从数据库中获取的日期时间,这个日期时间是 UTC 日期时间。但是当我从数据库中提取它时,它不知道时区。我需要做的是将这个日期时间转换为另一个函数的“从纪元开始的秒数”时间。这样做的问题是,系统的时间是 PST,由于特定原因我无法更改它。

所以,我想做的是,从数据库中获取这个日期时间,并告诉 python 这个日期时间是 UTC 日期时间。我所做的每一种方式都会导致由于时区转换而失去时间或获得时间。同样,不尝试转换时间,只是尝试指定它是 UTC。

如果有人能提供帮助,那就太好了。

谢谢!

例子

假设 database_function() 返回的日期时间数据类型为 '2013-06-01 01:06:18'

datetime = database_function()
epoch = datetime.strftime('%s')

pytz.utc.localize(database_function()).datetime.strftime('%s')
datetime.replace(tzinfo=pytz.utc).datetime.strftime('%s')

这两个都返回 1370077578 的纪元时间戳 但是,它应该返回一个时间戳为 1370048778 每个http://www.epochconverter.com/ 请记住,此时间戳是 UTC 时间戳

【问题讨论】:

  • 我尝试按照那里的建议进行操作,但它最终转换了日期时间,使它比原来晚了 8 小时(认为我给它的时间是一个正在转换为 UTC 的 PST 时间)同样,不要试图隐藏一个日期时间,而是试图指定日期时间是什么,所以我在使用它时得到了正确的“从纪元开始的秒数”时间。
  • 那你有没有看这个:stackoverflow.com/questions/4548684/…
  • 那个网站似乎有问题 - 转换 2013-06-01 01:06:18 时,我得到 1370045178
  • 其他阅读本文的人:datetime == datetime.datetime(2013, 6, 1, 1, 6, 18)。 @OP:不要在模块之后命名你的变量!

标签: python datetime timezone


【解决方案1】:

您可以使用pytz,这是一个时区定义包。

from datetime import datetime
from pytz import timezone

fmt = "%Y-%m-%d %H:%M:%S %Z%z"

# Current time in UTC
now_utc = datetime.now(timezone('UTC'))
print now_utc.strftime(fmt)

# Convert to US/Pacific time zone
now_pacific = now_utc.astimezone(timezone('US/Pacific'))
print now_pacific.strftime(fmt)

# Convert to Europe/Berlin time zone
now_berlin = now_pacific.astimezone(timezone('Europe/Berlin'))
print now_berlin.strftime(fmt)

输出:

2014-04-04 21:50:55 UTC+0000
2014-04-04 14:50:55 PDT-0700
2014-04-04 23:50:55 CEST+0200

或许有帮助

>> import pytz
>>> import datetime
>>>
>>> now_utc = datetime.datetime.utcnow() #Our UTC naive time from DB,
   for the time being here I'm taking it as current system UTC time..
>>> now_utc
    datetime.datetime(2011, 5, 9, 6, 36, 39, 883479) # UTC time in Naive
   form.
>>>
>>> local_tz = pytz.timezone('Europe/Paris') #Our Local timezone, to
   which we want to convert the UTC time.
>>>
>>> now_utc = pytz.utc.localize(now_utc) #Add Timezone information to
   UTC time.
>>>
>>> now_utc
datetime.datetime(2011, 5, 9, 6, 36, 39, 883479, tzinfo=<UTC>) # The
   full datetime tuple
>>>
>>> local_time = now_utc.astimezone(local\_tz) # Convert to local
   time.
>>>
>>> local_time #Current local time in Paris
datetime.datetime(2011, 5, 9, 8, 36, 39, 883479, tzinfo=<DstTzInfo
   'Europe/Paris' CEST+2:00:00 DST>)

【讨论】:

  • 再一次,我不想转换日期时间,我有一个日期时间是时区 UNAWARE 但我知道它是 UTC 日期时间,我如何告诉 python 它是 UTC 日期时间。
【解决方案2】:

使用神话般的pytz

import datetime, pytz
dt = datetime.datetime(...)
utc_dt = pytz.utc.localize(dt)

这将创建一个 tz 感知的日期时间对象,采用 UTC。

【讨论】:

  • 这会返回一个错误:ValueError: astimezone() cannot be applied to a naive datetime
  • @user2146933:注意:如果dt 还不是UTC,它会产生不正确的结果。另一方面,如果dt is 已经在 UTC 中,那么您在这里不需要pytz,您可以使用stdlib-only solutionutc_dt_aware = utc_dt_naive.replace(tzinfo=timezone.utc)
【解决方案3】:

Setting timezone in Python 怎么样?这似乎会在你的 python 脚本中重置时区。您正在更改系统在指定时间看到的时区,而不是将指定时间更改为指定时区。您可能希望将其设置为“UTC”

time.tzset()

重置库例程使用的时间转换规则。
环境变量 TZ 指定了这是如何完成的。

2.3 版中的新功能。

可用性:Unix。

我的家庭平台上没有此功能,因此无法对其进行测试。我必须从上一个答案中得到这个。

在该问题上标记为最佳的答案是:

>>> import os, time
>>> time.strftime('%X %x %Z')
'12:45:20 08/19/09 CDT'
>>> os.environ['TZ'] = 'Europe/London'
>>> time.tzset()
>>> time.strftime('%X %x %Z')
'18:45:39 08/19/09 BST'

要获取您列出的具体值:

>>> year = time.strftime('%Y')
>>> month = time.strftime('%m')
>>> day = time.strftime('%d')
>>> hour = time.strftime('%H')
>>> minute = time.strftime('%M')

有关指令的完整列表,请参阅here。请记住,strftime() 函数将始终返回一个字符串,而不是整数或其他类型。

【讨论】:

    【解决方案4】:

    这是一种方法,使用 pytz 模块:

    import pytz
    utc_datetime = (datetime.datetime(1970, 1, 1, tzinfo=pytz.utc)
                    + datetime.timedelta(seconds=seconds_since_epoch)
    

    如果您不想安装 pytz 模块,可以从 datetime 文档中复制示例 UTC 类(搜索“class UTC”):

    https://docs.python.org/2/library/datetime.html#tzinfo-objects

    【讨论】:

      【解决方案5】:

      这是没有 3 方模块的仅 stdlib 解决方案。

      ..,这个日期时间是 UTC 日期时间。但是当我从数据库中提取它时,它不知道时区。我需要做的是,将此日期时间转换为 “距纪元的秒数​​” 用于另一个功能的时间。强调是我的

      将表示 UTC 时间的未知(原始)日期时间对象转换为 POSIX 时间戳:

      from datetime import datetime
      
      timestamp = (dt_from_db - datetime(1970, 1, 1)).total_seconds()
      

      例子:

      >>> from datetime import datetime
      >>> dt = datetime.strptime('2013-06-01 01:06:18', '%Y-%m-%d %H:%M:%S')
      >>> (dt - datetime(1970, 1, 1)).total_seconds()
      1370048778.0
      

      请参阅Converting datetime.date to UTC timestamp in Python,它为各种 Python 版本提供解决方案。

      回答标题中的问题:一般来说,您需要pytz 库来处理Python 中的时区。特别是,您应该使用.localize 方法将不知道的日期时间对象转换为可感知时区的对象。

      import pytz # $ pip install pytz
      from tzlocal import get_localzone # $ pip install tzlocal
      
      tz = get_localzone() # local timezone whatever it is (just an example)
      aware_dt = tz.localize(naive_dt_in_local_timezone, is_dst=None)
      

      is_dst=None 断言 naive_dt_in_local_timezone 存在且明确。

      虽然您在 UTC 时区不需要它,因为它在全年和过去所有年份中始终具有相同的 UTC 偏移量(零):

      import pytz
      
      aware_dt = utc_dt.replace(tzinfo=pytz.utc)
      

      Python - simplest and most coherent way to get timezone-aware current time in UTC?(它提供了stdlib-only solution):

      aware_dt = utc_dt.replace(tzinfo=timezone.utc)
      

      【讨论】:

      • utc_dttimezone 未定义。目前尚不清楚它们来自哪里。
      • @sebix: utc_dt: 是一个表示 UTC 时间的天真日期时间对象(请阅读问题中的第一句)。该公式来自另一个答案(它演示了仅限 stdlib 的解决方案——查看它之前的链接)。 Follow the links, to see timezone definition.
      猜你喜欢
      • 2011-09-08
      • 2011-05-03
      • 2021-12-06
      • 2018-11-25
      • 2011-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-01
      相关资源
      最近更新 更多