【问题标题】:Is it safe to convert ISO datetime with strtotime使用 strtotime 转换 ISO 日期时间是否安全
【发布时间】:2021-09-13 11:56:39
【问题描述】:

例如

strtotime("2018-12-06T09:04:55");
strtotime("2021-07-09T14:09:47.529751-04:00");

我在 php 手册中读到使用 strtotime 时应避免使用 ISO 日期,为什么? 我应该在使用 strtotime 之前从字符串中提取日期时间吗?

strtotime() 将转换没有时区指示的字符串,就好像该字符串是默认时区 ( date_default_timezone_set() ) 中的时间。因此,使用 strtotime() 转换像 '2018-12-06T09:04:55' 这样的 UTC 时间实际上会产生错误的结果。在这种情况下使用:

<?php
function UTCdatestringToTime($utcdatestring)
{
    $tz = date_default_timezone_get();
    date_default_timezone_set('UTC');

    $result = strtotime($utcdatestring);

    date_default_timezone_set($tz);
    return $result;
}
?>

【问题讨论】:

  • 您指的是哪本手册?我在docs 中看到的唯一警告是:“此函数返回的 Unix 时间戳不包含有关时区的信息。为了使用日期/时间信息进行计算,您应该使用功能更强大的 DateTimeImmutable。”
  • 我读到的只是“为了避免潜在的歧义,最好尽可能使用 ISO 8601 (YYYY-MM-DD) 日期或 DateTime::createFromFormat()。”并且可以追溯到 10 年前的顶级帖子说您应该在日期组件之间使用点 .,因为 strtotime() 在设计上是“智能的”。这提醒我们EWD 340

标签: php date time unix-timestamp strtotime


【解决方案1】:

如果日期字符串包含时区,strtotime 也会考虑到这一点。

$strDate = "2018-12-06T09:04:55 UTC";
$ts = strtotime($strDate);  // int(1544087095)

如果日期字符串中缺少时区,则使用默认时区。我的时区是“欧洲/柏林”。

$strDate = "2018-12-06T09:04:55";
$ts = strtotime($strDate);  // int(1544083495)

因此,我们得到不同的时间戳。

如果我想将另一个时区的日期字符串转换为时间戳,那么最好的解决方案是使用 DateTime 对象。创建对象时,我可以在第二个参数中输入正确的时区。

$strDate = "2018-12-06T09:04:55";
$dt = new DateTime($strDate, new DateTimeZone('UTC'));
$ts = $dt->getTimeStamp();  // int(1544087095)

重要提示:如果日期字符串包含有效的时区,则它优先于第二个参数。

$strDate = "2018-12-06T09:04:55 UTC";
$dt = new DateTime($strDate, new DateTimeZone('Europe/Berlin'));
/*
DateTime::__set_state(array(
   'date' => "2018-12-06 09:04:55.000000",
   'timezone_type' => 3,
   'timezone' => "UTC",
))
*/

此处忽略 DateTimeZone('Europe/Berlin')。

由于 strtotime 也接受日期字符串中的时区,因此也可以使用字符串连接添加时区。

$strDate = "2018-12-06T09:04:55";
$ts = strtotime($strDate." UTC");  //int(1544087095)

UTCdatestringToTime 函数也是如此。但是,暂时更改 PHP 脚本中的默认时区并不好。

【讨论】:

    猜你喜欢
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多