DateTime 对象上的不同 timezone_types

Posted

技术标签:

【中文标题】DateTime 对象上的不同 timezone_types【英文标题】:Different timezone_types on DateTime object 【发布时间】:2013-07-15 17:12:47 【问题描述】:

我在 Postgres 上使用 Doctrine2。在一张表中,我有两种不同的日期类型:birthdate:datecreated_at:datetimetz。两者都成为 DateTime 对象,但具有不同的timezone_type。 以下是列表:

created_atdatetimetz:

DateTime Object
(
    [date] => 2013-04-18 11:54:34
    [timezone_type] => 1
    [timezone] => +02:00
)

birthdate日期:

DateTime Object
(
    [date] => 1970-01-01 00:00:00
    [timezone_type] => 3
    [timezone] => Europe/Berlin
)

我需要以同样的方式格式化我的对象。两者都应该有timezone_type=3

我怎样才能做到这一点?

【问题讨论】:

date_timezone_set ( DateTime $object , DateTimeZone $timezone ) 您建议的代码仅设置时区。在上面的列表中,时区是相同的,但它们的显示方式不同。 如果你在每一个上都使用$mytime->setTimezone(new DateTimezone('Europe/Berlin'))(或其他),结果将是它们以相同的方式呈现。 【参考方案1】:

时区可以是 DateTime 对象中的三种不同类型之一:

1 型; UTC 偏移量,例如 new DateTime("17 July 2013 -0300"); 2 型;时区缩写,例如new DateTime("17 July 2013 GMT"); 类型 3:时区标识符,例如new DateTime( "17 July 2013", new DateTimeZone("Europe/London"));

只有附加了类型 3 时区的 DateTime 对象才能正确使用 DST。

为了始终拥有类型 3,您需要将时区作为来自this list 的接受标识符存储在数据库中,并在实例化时将其应用于您的 DateTime 对象。

【讨论】:

嗯.. 我确实将这种类型 3 时区存储在数据库中。似乎是一个问题,Doctrine2 返回那些不同的时区类型(即使我明确地将时区传递为 \DateTimeZone("Europe/London"))。我不认为我可以轻松地修改 Doctrine2 行为,因此我已经决定在消费者类中使用简单的时间戳来进行日期时间格式化。或者,也许我留下了一些未被注意到的东西?您是否曾在 Doctrine2+Postgres 中处理过 DateTime 对象并使其工作? 在使用不同的 ORM 时遇到同样的问题,我发现 $new=new DateTime(); $new->setTimestamp($old->getTimestamp()); 可以解决问题,尽管非常难看。在 setter 中包含这个可以减轻痛苦。 @Softlion 如果我在类型 1 中的 DateTime 中添加 6 个月,它将需要 1 小时,因为它不知道 10 月左右某个时间发生的 DST 转换。类型 3 将正确解释转换。 @vascowhite 此映射是否在任何地方的文档中列出? @GPHemsley 我不这么认为。我通过测试和阅读源代码发现了它。我依稀记得在某处看到了一条评论,证实了我的发现,但那是很久以前的事了,我不记得在哪里了。【参考方案2】:

我知道这是一个古老的帖子,但由于提到了 Doctrine,我觉得有必要分享我最近在这个问题上的经历。

@vascowhite 是正确的,但是关于通过 HTTP 发送到服务器(例如保存)的 Doctrine(至少在我的配置中)日期被转换为时区类型 2。Doctrine 正确处理它们并正确保存日期,但它确实 不转换时区类型。

如果您正在执行“保存并返回新值”类型的操作,请注意 Doctrine 将使用缓存值(timezone_type 2)。当您期望 timezone_type 3 时,这变得很重要,因为您通常会在页面重新加载期间得到。我们有一个自定义日期转换器 JS 类,它需要 timezone_type 3,但它无法转换它。诚然,日期转换器应该考虑到这一点,但也应该知道时区类型将是 Doctrine 中最后加载的值。保存后清除 Doctrine 的缓存将强制使用 timezone_type 3 重新加载数据。

【讨论】:

以上是关于DateTime 对象上的不同 timezone_types的主要内容,如果未能解决你的问题,请参考以下文章

为啥 python datetime replace timezone 返回不同的时区?

pandas使用to_datetime函数将时间字符串转化为时间对象使用dt.tz_localize为转化后的时间对象添加时区信息(timezone)

如何在 python 中使用带有 datetime 对象的时区?

如何在 python 中使用带有 datetime 对象的时区?

python datetime时区转换

[转] datetime.nowdatetime.utcnow以及Django中的timezone.now之间的区别