Как разобрать строку с сокращением часового пояса BRT в PHP - PullRequest
4 голосов
/ 03 мая 2020

У меня разные строки в разных часовых поясах:
2019-11-13 00:52:03 ADT
2019-11-13 00:52:03 EET
2019-11- 13 00:52:03 BRT

Я использую формат Y-m-d H:i:s T с DateTime::createFromFormat, чтобы получить объект даты и времени.

Но следующий код возвращает FALSE:
DateTime::createFromFormat('Y-m-d H:i:s T', '2019-11-13 00:52:03 BRT')

Проблема: PHP не распознает BRT сокращение часового пояса .

Есть ли способ преодолеть это?
Например, можно ли добавить новую аббревиатуру в список PHP часовых поясов?

PS

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

Возвращает America/Sao_Paulo => -03

Ответы [ 2 ]

0 голосов
/ 03 мая 2020

вы можете попробовать заменить неподдерживаемый часовой пояс на соответствующий поддерживаемый часовой пояс или смещение перед преобразованием строки в объект 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);
0 голосов
/ 03 мая 2020

Нет, вы не можете добавлять новые сокращения часовых поясов к PHP. PHP получает эти часовые пояса из встроенной базы данных часовых поясов, которая основана на базе данных Олсона .

Однако вы можете предоставлять литералы в DateTime::createFromFormat, экранируя их с помощью обратного слэса. sh символ. Так что в вашем случае вам нужно будет установить часовой пояс вручную, если он потерпит неудачу. Вы можете проверить, не совпадает ли сокращение часового пояса в базе данных, используя 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"
}

Вам нужно будет разработать свой собственный лог c для обработки неопределенных часовых поясов, но это должно дать вам представление о том, как действовать дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...