【问题标题】:Python convert timestamps with specific timezone to datetime in UTCPython将具有特定时区的时间戳转换为UTC中的日期时间
【发布时间】:2017-05-27 14:23:58
【问题描述】:

我正在尝试将具有特定时区(欧洲/巴黎)的时间戳转换为 UTC 的日期时间格式。 在我的笔记本电脑上,它适用于以下解决方案,但是当我在远程服务器(爱尔兰的 AWS-Lambda 函数)中执行我的代码时,我有 1 小时的班次,因为服务器的本地时区与我的不同。 我怎样才能拥有一个可以在我的笔记本电脑上同时在远程服务器上工作的代码(动态处理本地时区)?

import pytz
import datetime

def convert_timestamp_in_datetime_utc(timestamp_received):
    utc = pytz.timezone('UTC')
    now_in_utc = datetime.datetime.utcnow().replace(tzinfo=utc).astimezone(pytz.UTC)
    fr = pytz.timezone('Europe/Paris')
    new_date = datetime.datetime.fromtimestamp(timestamp_received)
    return fr.localize(new_date, is_dst=None).astimezone(pytz.UTC)

谢谢

【问题讨论】:

  • 我不确定我是否理解这个问题 - 这是怎么失败的?什么是“timestamp_received”?我可以想象这种失败的唯一原因是时间戳是否是本地时间的时间戳。
  • 这是一个从法国网站提取的时间戳,基于当地时区(欧洲/巴黎)。当我执行此函数时,如果我在笔记本电脑上或通过 Lambda 函数执行它,则返回日期时间会偏移一小时。我想问题是“datetime.datetime.fromtimestamp”是基于当地时区的......

标签: python datetime pytz


【解决方案1】:

我不确定timestamp_received 是什么,但我想你想要的是utcfromtimestamp()

import pytz
from datetime import datetime

def convert_timestamp_in_datetime_utc(timestamp_received):
    dt_naive_utc = datetime.utcfromtimestamp(timestamp_received)
    return dt_naive_utc.replace(tzinfo=pytz.utc)

为了完整起见,这里是通过引用python-dateutiltzlocal 时区来完成同样事情的另一种方法:

from dateutil import tz
from datetime import datetime
def convert_timestamp_in_datetime_utc(timestamp_received):
    dt_local = datetime.fromtimestamp(timestamp_received, tz.tzlocal())

    if tz.datetime_ambiguous(dt_local):
        raise AmbiguousTimeError

    if tz.datetime_imaginary(dt_local):
        raise ImaginaryTimeError

    return dt_local.astimezone(tz.tzutc())


class AmbiguousTimeError(ValueError):
    pass

class ImaginaryTimeError(ValueError):
    pass

(我在AmbiguousTimeErrorImaginaryTimeError 条件中添加了模拟pytz 接口的条件。)请注意,我将其包括在内,以防您遇到类似问题需要参考本地时区出于某种原因 - 如果您有一些东西可以在 UTC 中为您提供正确的答案,最好使用它,然后使用 astimezone 将其放入您想要的任何本地区域。

工作原理

由于您表示您仍然对它在 cmets 中的工作方式感到有些困惑,所以我想我会澄清为什么会这样。有两个函数可以将时间戳转换为datetime.datetime 对象,datetime.datetime.fromtimestamp(timestamp, tz=None)datetime.datetime.utcfromtimestamp(timestamp)

  1. utcfromtimestamp(timestamp) 会给你一个 naive datetime,它代表 UTC 时间。然后,您可以执行 dt.replace(tzinfo=pytz.utc)(或任何其他 utc 实现 - datetime.timezone.utcdateutil.tz.tzutc() 等)来获取可感知的日期时间并将其转换为您想要的任何时区。

  2. fromtimestamp(timestamp, tz=None),当tz 不是None 时,会给你一个aware datetime 等同于utcfromtimestamp(timestamp).replace(tzinfo=timezone.utc).astimezone(tz)。如果tzNone,它不会转换太指定时区,而是转换为您的本地时间(相当于dateutil.tz.tzlocal()),然后返回一个naivedatetime

从 Python 3.6 开始,您可以在 naive 日期时间上使用datetime.datetime.astimezone(tz=None),并且时区将被假定为系统本地时间。因此,如果您正在开发 Python >= 3.6 应用程序或库,则可以使用 datetime.fromtimestamp(timestamp).astimezone(whatever_timezone)datetime.utcfromtimestamp(timestamp).replace(tzinfo=timezone.utc).astimezone(whatever_timezone) 作为等效项。

【讨论】:

  • 非常感谢 Paul,它适用于第一个解决方案!对我来说仍然很困惑不同时区的日期时间/时间戳操作:(
  • @Matt 我更新了我的答案,希望能澄清发生了什么。
  • 非常感谢您的解释!现在对我来说更清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
  • 1970-01-01
  • 2013-12-04
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多