PHP 与夏令时相关的日期时间转换问题
PHP date time conversion issues related to daylight savings
我的网络应用程序中有一些本地化功能(通过 Ajax 公开),使用户能够在他们自己的时区以及与数据主要相关的实体位置相关的时区显示一些日期时间信息到.
作为一些测试的结果,我发现虽然我的代码能够准确地转换源自数据库的 date/time 值(即包括 DST 调整),但当我正在使用表格中提供的日期。我所能达到的最好结果是将 date/time 形式的值转换为 UTC,但应用了不正确的偏移量。这意味着我需要检查日期是否在夏令时范围内,如果是,则将日期时间值向后拉一小时。这似乎是一个丑陋的修复,如果有人知道我哪里出错了,我将不胜感激:
示例:
- 输入值 25/11/2018 16:00 NZDT (Pacific/Auckland) = UTC+13
- 输出值应为 25/11/2018 14:00 ADT (Australia/Sydney) = UTC+11
- 如果我从数据库中提取源值然后进行转换,则计算工作正常,没有问题
如果我使用表单提供的值(我需要检查以防用户在没有保存的情况下更新了值),则会发生以下情况:
FROM DB1 = 2018-11-25 03:00:00(数据库中的值,UTC)
- FROM FORM1 = 25/11/2018 16:00(表格的原始值)
- FROM FORM2 = 2018-11-25 04:00:00(更改为 UTC-12,即 NZST)这是错误的,应该与 DB1 的值相同,即 UTC-13 是与 NZDT 的偏移量回到 UTC)
- FROM FORM3 = 2018-11-25 03:00:00(已更正,一旦我检查 date/time 值是否在夏令时范围内)
代码如下:
echo "FROM DB1: ".$getListing['lo_deadline']."<BR />";
echo "FROM FORM1:".$in_lo_deadline."<BR />";
$frmDateTime = DateTime::createFromFormat($this->view->user->user_datetimeformat, $in_lo_deadline,new DateTimeZone($list_tmzn));
echo "FROM FORM2:".$frmDateTime->format('Y-m-d h:i:s')."<BR />";
//If $frmDateTime is in daylight savings then subtract an hour to arrive at the correct UTC value
if ($frmDateTime->format('I'))
{
date_sub($frmDateTime, date_interval_create_from_date_string('1 hours'));
}
echo "FROM FORM3:".$frmDateTime->format('Y-m-d h:i:s')."<BR />";
$dates['set_dead'] = convertUserDate($frmDateTime->format('Y-m-d h:i:s'), $this->view->user->user_datetimeformat, $user_tmzn,'UTC');
我从你的代码中了解到,它显示 2018-11-25 04:00:00
的原因是 AM/PM 格式。您应该在代码中使用大写 H
而不是 h
。
您需要了解 24 小时制和 12 小时制之间的区别。 2018-11-25 04:00:00
根据您的格式是 AM/PM 或 12 小时格式,但在 24 小时格式中它应该是 2018-11-25 16:00:00
。数据库时间始终采用 24 小时格式。
改变
$frmDateTime->format('Y-m-d h:i:s')
至
$frmDateTime->format('Y-m-d H:i:s')
注意:您不需要手动减去一个小时来计算夏令时,因为 php 会自动执行。
我的网络应用程序中有一些本地化功能(通过 Ajax 公开),使用户能够在他们自己的时区以及与数据主要相关的实体位置相关的时区显示一些日期时间信息到.
作为一些测试的结果,我发现虽然我的代码能够准确地转换源自数据库的 date/time 值(即包括 DST 调整),但当我正在使用表格中提供的日期。我所能达到的最好结果是将 date/time 形式的值转换为 UTC,但应用了不正确的偏移量。这意味着我需要检查日期是否在夏令时范围内,如果是,则将日期时间值向后拉一小时。这似乎是一个丑陋的修复,如果有人知道我哪里出错了,我将不胜感激:
示例:
- 输入值 25/11/2018 16:00 NZDT (Pacific/Auckland) = UTC+13
- 输出值应为 25/11/2018 14:00 ADT (Australia/Sydney) = UTC+11
- 如果我从数据库中提取源值然后进行转换,则计算工作正常,没有问题
如果我使用表单提供的值(我需要检查以防用户在没有保存的情况下更新了值),则会发生以下情况:
FROM DB1 = 2018-11-25 03:00:00(数据库中的值,UTC)
- FROM FORM1 = 25/11/2018 16:00(表格的原始值)
- FROM FORM2 = 2018-11-25 04:00:00(更改为 UTC-12,即 NZST)这是错误的,应该与 DB1 的值相同,即 UTC-13 是与 NZDT 的偏移量回到 UTC)
- FROM FORM3 = 2018-11-25 03:00:00(已更正,一旦我检查 date/time 值是否在夏令时范围内)
代码如下:
echo "FROM DB1: ".$getListing['lo_deadline']."<BR />";
echo "FROM FORM1:".$in_lo_deadline."<BR />";
$frmDateTime = DateTime::createFromFormat($this->view->user->user_datetimeformat, $in_lo_deadline,new DateTimeZone($list_tmzn));
echo "FROM FORM2:".$frmDateTime->format('Y-m-d h:i:s')."<BR />";
//If $frmDateTime is in daylight savings then subtract an hour to arrive at the correct UTC value
if ($frmDateTime->format('I'))
{
date_sub($frmDateTime, date_interval_create_from_date_string('1 hours'));
}
echo "FROM FORM3:".$frmDateTime->format('Y-m-d h:i:s')."<BR />";
$dates['set_dead'] = convertUserDate($frmDateTime->format('Y-m-d h:i:s'), $this->view->user->user_datetimeformat, $user_tmzn,'UTC');
我从你的代码中了解到,它显示 2018-11-25 04:00:00
的原因是 AM/PM 格式。您应该在代码中使用大写 H
而不是 h
。
您需要了解 24 小时制和 12 小时制之间的区别。 2018-11-25 04:00:00
根据您的格式是 AM/PM 或 12 小时格式,但在 24 小时格式中它应该是 2018-11-25 16:00:00
。数据库时间始终采用 24 小时格式。
改变
$frmDateTime->format('Y-m-d h:i:s')
至
$frmDateTime->format('Y-m-d H:i:s')
注意:您不需要手动减去一个小时来计算夏令时,因为 php 会自动执行。