不使用UTC显示时区

Alt*_*irl 5 php timezone datetime

我一直在阅读如何在整个上午这样做,并且普遍的共识是:将您的时间戳存储在UTC中并从那里计算偏移量.

但是,像大多数人一样,我维护现有的代码库,但我无法改变存储日期的方式.至少,不是在规定的时间范围内.

所以我的问题是,我可以安全地做这样的事吗?

// this is my time zone
$timestamp = strtotime($timestampFromDatabase);
date_default_timezone_set('America/New York');
$tz = date_default_timezone_get();

// this is theoretically their timezone, which will eventually
// be taken from a session variable
date_default_timezone_set('Europe/Paris');
$offset = time() - $timestamp;
$timestamp -= $offset;

// now that I have the offset, display dates like this
date('r', $timestamp);
Run Code Online (Sandbox Code Playgroud)

有些人建议不要做日期算术,但是我在这里做错了什么?有没有更好的办法?是否有需要注意的陷阱?我特别感兴趣的是这种方法可以产生什么样的错误,如果有的话,他们会影响谁?

我的老板是那种不关心这个bug只影响1%用户群的人.

编辑:我可以更清楚地说明这一点吗?我似乎没有太多的接受者.任何人?即使是模糊的建议或链接也会非常有用.

Dav*_*unt 5

简短的回答是时区很难处理,没有人愿意解决困难的问题!

更长的答案是这样的:

首先,您需要在当前时区创建日期的表示.以下是等效的:

date_default_timezone_set('America/New York');

$date = new DateTime(null);
Run Code Online (Sandbox Code Playgroud)

要么

$date = new DateTime(null, new DateTimeZone('America/New York'));   
Run Code Online (Sandbox Code Playgroud)

这将为您提供设置为America/New York的区域的日期.我们可以轻松地将其转换为用户时区,在本例中为欧洲/巴黎,下一行:

$date->setTimezone(new DateTimeZone('Europe/London'));
Run Code Online (Sandbox Code Playgroud)

您可以使用以下行来获取任何时刻表示的日期/时间.

echo $date->format('d/m/Y H:i:s');
Run Code Online (Sandbox Code Playgroud)

强烈建议使用算术,因为内置的PHP函数知道夏令时和许多复杂的事情,你不会正确.


我的测试脚本完整:

date_default_timezone_set('America/Belize');

$date = new DateTime(null);

echo $date->format('d/m/Y H:i:s') . '<br>';

$date->setTimezone(new DateTimeZone('Europe/London'));

echo $date->format('d/m/Y H:i:s') . '<br>';
Run Code Online (Sandbox Code Playgroud)