当前位置: 首页 > 知识库问答 >
问题:

如何在CEST和UTC时区之间转换日期时间对象

郦翰学
2023-03-14

我不想使用 pytz 库,因为我正在处理的项目需要文书工作来引入依赖项。如果我能在没有第三方库的情况下实现这一目标,我会更高兴。

我很难在CET和UTC之间转换日期,因为日期是夏时制。这与我预期的相差一个小时:

>>> print from_cet_to_utc(year=2017, month=7, day=24, hour=10, minute=30)
2017-07-24T09:30Z

2017-07-24T08:30Z  # expected

CET比UTC提前一小时,夏季提前2小时。因此,我预计中欧在盛夏的10点30分将达到协调世界时的8点30分。

功能是:

from datetime import datetime, tzinfo, timedelta

def from_cet_to_utc(year, month, day, hour, minute):
    cet = datetime(year, month, day, hour, minute, tzinfo=CET())
    utc = cet.astimezone(tz=UTC())
    return '{:%Y-%m-%d:T%H:%MZ}'.format(utc)

我使用两个时区信息对象:

class CET(tzinfo):
    def utcoffset(self, dt):
        return timedelta(hours=1)

    def dst(self, dt):
        return timedelta(hours=2)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return timedelta(0)

    def dst(self, dt):
        return timedelta(0)

共有2个答案

子车成和
2023-03-14

你应该仔细阅读tzinfo手册,正如上面所解释的那样。

首先,dst() 通常应该返回 timedelta(0) 或 timedeltahours=1),永远不会返回 2 小时或更长时间,很少返回介于两者之间的时间(例如 30 分钟)。这只是相对于正常TZ偏移的dst偏移,而不是dst模式下的全部TZ偏移。

其次,utcoffset()必须已经包含dst校正。dst()方法本身也用于手册中描述的某些情况(例如,用于检测dst是否有效),但除非您这样做,否则它不会自动应用于TZ偏移。

您的代码应如下所示:

from datetime import datetime, tzinfo, timedelta

class CET(tzinfo):
    def utcoffset(self, dt):
        return timedelta(hours=1) + self.dst(dt)

    def dst(self, dt):
        dston = datetime(year=dt.year, month=3, day=20)
        dstoff = datetime(year=dt.year, month=10, day=20)
        if dston <= dt.replace(tzinfo=None) < dstoff:
            return timedelta(hours=1)
        else:
            return timedelta(0)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return timedelta(0)

    def dst(self, dt):
        return timedelta(0)

def from_cet_to_utc(year, month, day, hour, minute):
    cet = datetime(year, month, day, hour, minute, tzinfo=CET())
    utc = cet.astimezone(tz=UTC())
    return '{:%Y-%m-%d:T%H:%MZ}'.format(utc)


print from_cet_to_utc(year=2017, month=7, day=24, hour=10, minute=30)
# 2017-07-24:T08:30Z

在这里,我勇敢地假设 DST 实际上是 20.03.YYYY - 19.10.YYYY(含),其中 YYYY 是日期/日期时间对象的年份。

通常这种on的逻辑

邵羽
2023-03-14

只是补充@Sergey的答案。

要知道何时应用DST,您应该获取DST开始和结束的日期/时间的历史数据,并检查是否必须将其应用于指定的日期时间。您可以从IANA数据库中获取这些信息,也可以在许多在线资源中查阅,如时间和日期网站。

另一个细节是CET是一个模糊的名称,因为它被多个时区使用。实时时区名称使用IANA数据库定义的名称(始终采用< code >地区/城市格式,如< code >欧洲/巴黎或< code >欧洲/柏林)。

我将以欧洲/柏林时区为例。今年(2017年),柏林DST于3月26日开始:凌晨2点,时钟向前移动1小时至凌晨3点,偏移量从<code>01:00</code>变为<code>02:00</ccode>。

您还可以认为时钟直接从凌晨 1:59 跳到凌晨 3 点,这意味着凌晨 2 点到凌晨 2:59 之间的所有当地时间在那一天的时区都不存在。这称为间隙,您应该检查这种情况(一种常见的方法是将凌晨 2 点调整为下一个有效小时 - 在本例中为夏令时凌晨 3 点)。

在同一时区,2017年,夏令时将于10月29日th结束:凌晨3点,时钟将后移1小时至凌晨2点,偏移量将从02:00变为01:00

这意味着凌晨 2 点到凌晨 2:59 之间的所有本地时间将存在两次:一次在 DST (02:00) 中,一次在非 DST (01:00)。这称为重叠,在这种情况下创建日期时间时,您必须决定选择创建哪个日期时间(应该是 DST 的凌晨 2 点还是非 DST 偏移量?您决定!

附言:现在每个使用CET的欧洲国家都在不同的年份采用它,所以如果你在处理旧日期,你也必须考虑到这一点。

另一个细节是夏令时是由政府定义的,不能保证规则会永远这样,你必须相应地更新规则——使用pytz的另一个优势,因为它的更新是从IANA版本生成的,并在PyPI中发布(感谢@Matt Johnson指向此信息)。

你确定文书工作比手工编写这些规则更糟糕吗?只是检查如何阅读IANA tz文件,也许你会改变主意。

 类似资料:
  • 问题内容: 这是我的约会日期“ 15-05-2014 00:00:00” 如何将IST转换为UTC即(到14-05-2014 18:30:00) 基于时区到UTC时区。 我的代码是 如果用户从任何区域输入相同的日期,则将获得UTC时间(例如:从澳大利亚,然后从15-05-2014 00:00:00到14-05-2014 16:00:00) 请任何建议。 问题答案: 您不能将日期值“转换为”其他时区

  • > 如何将IST转换为UTC,即(至2014年5月14日18:30:00) 我的代码是 > 如果用户从任何区域输入相同的日期,则将获得UTC时间(例如:从澳大利亚输入,然后是2014年5月15日00:00:00至2014年5月14日16:00:00) 请提出任何建议。

  • 我有一个方法可以生成一个随机的日期和时间。 打印输出类似于 我见过几个这样的问题和页面,但他们没有给我一个线索。

  • 问题内容: 如何将这样的日期(在时区中)转换为时区?确保夏令时能正确处理? 问题答案: 使用和。

  • 问题内容: 从服务器上,我得到了这种格式的datetime变量:它是UTC时间。我想使用JavaScript将其转换为当前用户的浏览器时间。 如何使用JavaScript或jQuery完成此操作? 问题答案: 在将字符串转换为javascript中的日期之前,将’UTC’附加到字符串中:

  • 问题内容: 我需要一种简便的方法,可以在不使用任何库的情况下将日期时间戳转换为UTC(从服务器所在的任何时区)。 问题答案: 尝试getTimezone和setTimezone,请参见示例 (但这确实使用了一个类) 更新: 没有任何类,您可以尝试这样的事情: 注意:您可能还需要将时区设置回原始