3

我读得越多,我就越困惑。

我的项目计划是在 UTC 中处理所有日期/时间存储和计算,但显示该数据时除外。问题是服务器将移动到具有不同时区和夏令时信息的不同位置,因此我必须在 UI 中实现某种形式的时区选择器。

但是有各种例外情况会发生夏令时和没有夏令时,例如亚利桑那州除了纳瓦霍印第安人保留地之外没有夏令时。所以我不能简单地使用时区位置的 PHP 列表(例如'America/Phoenix'),因为我不知道服务器的实际位置是否会在这样一个区域,所以我猜我会必须实现一个“使用夏令时”复选框和一个带有简单时区信息的更基本的选择框,例如“CST -6”等。

我可以使用“美国/凤凰城”系统来显示城市列表,但这会导致列表非常长。但是如果我在我的列表中使用 EST/CST,那么对于有与没有 DST 的区域来说,它是不准确的,所以我认为如果没有“DST?”我就无法做到这一点。复选框。

但是,我刚刚尝试了 PHPDateTimeDateTimeZone'CST'、'CDT' 和 'CST6CDT',所有三个结果都在同一时间,无论是二月的日期还是六月的日期。我想,CDT应该有DST,CST应该没有DST,CST6CDT应该使用自动切换,但显然没那么简单……

所以......如果我正在使用 EST/CST/PST 等时区列表并希望能够通过复选框关闭 DST,我将如何在 PHP 代码中实现它?如何在支持打开或关闭 DST 的情况下告诉 PHP 将时间转换为正确的时区?

我知道基本代码,但不知道如何更改 DST:

$myTime = new DateTime('02/10/2013 08:00:00', new DateTimeZone('UTC'));
var_dump($myTime);  // UTC
$localTz = new DateTimeZone('America/Phoenix');  // selected by user
$myTime->setTimezone($localTz);
var_dump($myTime);  // Phoenix with local DST settings

在不同但相关的说明中,更改 Linux 服务器的位置是否会导致服务器的内部时钟更改时区?移动服务器会扰乱内部时钟并导致不正确的 UTC 时间戳吗?

4

2 回答 2

3

作为一个花了 13 个月的时间围绕这个进行重大重构的人,我可以告诉你:你必须存储用户意图时间,然后将其解码为查看器本地时间

我所说的“用户意图时间”是时间和用户时区的组合。随着 DST 的变化,您将需要使用这两条信息来解码为来自不同位置的用户显示的时间。我的意思不仅仅指春季和秋季转换发生时 - 我的意思是当政府更改 DST 法律并且更新 Olson tzdata 数据库时。

你确实有一个经常从 PECL 更新 tzdata 的 cron 工作,对吧?:)

你会想要使用 - 并且可能扩展 - PHP 的错误 DateTime 和 DateTimeZone 内置函数。他们是你唯一的希望。

于 2013-11-05T06:17:45.873 回答
1

您描述的方法之前已经完成,并且总是存在相同的问题:

  • 大多数用户不够聪明,不知道是否选中该框。
  • 甚至拥有该框也没有意义,因为时区规则包含有关 DST 是否适用、何时适用以及适用多少的所有详细信息。
  • 时区缩写不明确。例如,没有任何其他信息,您怎么知道这CST意味着美国中部标准时间?这可能意味着中国标准时间或古巴标准时间。这里有一个列表,说明了所有的变化。
  • 关于缩写应该是什么并不总是一致的。例如,夏威夷是 HST 还是 HAST?

始终最好使用实际的 IANA 时区标识符,例如America/PhoenixAmerica/Los_Angeles。如果您需要一种更简单的方法让您的用户选择正确的时区,请尝试使用基于地图的选择器,例如这个

澄清您对影响 PHP 的操作系统时区的担忧。

  • 如果您只是说new DateTime(),那么是的 - 它会选择默认时区。这可以通过调用来更改date_default_timezone_set,但初始设置来自date.timezonephp.ini 文件中的设置,或者来自TZ操作系统的环境变量。

  • 明确时区总是更好,这样您就不会受到任何这些默认值的影响。

    例如,要获取凤凰城的当前时间:

    new DateTime(null, new DateTimeZone('America/Phoenix'))
    

    要在 UTC 中获得它:

    new DateTime(null, new DateTimeZone('UTC'))
    
  • 您可以在有意义的地方使用 UTC,但这不是强制性的。最重要的是当您从数据库中保存/检索时,或者在通过 api、Web 服务等进行传输时。

  • 如果你总是明确的,那么服务器的时区并不重要。无论时区如何,Linux 都会将系统 bios 同步到 UTC。Windows 会将 bios 与本地时间同步,但有一些内部结构,因此您仍然可以始终获得正确的 UTC 时间。(相当丑陋,但有效)。

  • 但是,将服务器设置为 UTC 时区仍然是“最佳实践”。主要原因是让您及早发现您有时区相关的代码。(最糟糕的发现时间是在您没有计划的 DST 过渡期间的半夜。)

于 2013-06-17T15:58:16.817 回答