如何在 PHP 中解析带有 BRT 时区缩写的字符串

How to parser string with BRT time zone abbreviation in PHP

我在不同的时区有不同的字符串:
2019-11-13 00:52:03 日均时间
2019-11-13 00:52:03 东欧时间
2019-11-13 00:52:03 BRT

我使用格式 Y-m-d H:i:s TDateTime::createFromFormat 来获取日期时间对象。

但是下一个代码returns FALSE:
DateTime::createFromFormat('Y-m-d H:i:s T', '2019-11-13 00:52:03 BRT')

问题:PHP无法识别BRT缩写时区

有什么办法可以克服这个问题吗?
例如,我可以将新缩写添加到 PHP 时区列表吗?

P.S。

    date_default_timezone_set('America/Sao_Paulo');
    echo date_default_timezone_get();
    echo ' => '.date('T');

Returns America/Sao_Paulo => -03

不,您不能向 PHP 添加新的时区缩写。 PHP 从基于 Olson Database.

的内置时区数据库中获取这些时区

但是,您可以在 DateTime::createFromFormat 中提供文字,方法是使用反斜杠字符转义它们。因此,在您的情况下,如果失败,您将需要手动设置时区。您可以使用 DateTimezone::listAbbreviations().

测试时区缩写是否与数据库中的任何内容都不匹配

这是一个例子...

$defaultTZ = null;
$tzString = "2019-11-13 00:52:03 BRT";
$tzs = implode('|', array_keys(DateTimeZone::listAbbreviations()));

if (!preg_match("/(?: )(" . $tzs . ")$/i", $tzString)) {
    if (preg_match("/(?: )([A-Z]{3,4})$/", $tzString, $match)) {
        $tzAbr = "\" . implode("\", str_split($match[1]));
        $defaultTZ = new DateTimezone("America/Sao_Paulo");
    } else {
        // ohnoes something went horribly wrong
    }
} else {
    $tzAbr = "T";
}

$date = DateTime::createFromFormat("Y-m-d H:i:s $tzAbr", $tzString, $defaultTZ);

var_dump($date);

这给了你...

object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "2019-11-13 00:52:03.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(17) "America/Sao_Paulo"
}

对于如何处理未指定的时区,您必须制定自己的逻辑,但这应该让您了解如何从这里开始。

在将字符串转换为 DateTime 对象之前,您可以尝试将不受支持的时区替换为匹配的受支持时区或偏移量。

$date = "2019-11-13 00:52:03 America/Sao_Paulo";
$dateTime = new DateTime($date);
print_r($dateTime);

$date = "2019-11-13 00:52:03 -0300";
$dateTime = new DateTime($date);
print_r($dateTime);

$date = "2019-11-13 00:52:03";
$dateTime = new DateTime($date, new DateTimeZone('-0300'));
print_r($dateTime);