Это похоже на ошибку (или, по крайней мере, недокументированное ограничение ) с PHP ... Если мы попробуем 4 возможных перестановки пробелов:
var_dump(\DateTime::createFromFormat('Y-m-dTH:i:s', '2012-01-24MSK16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-d T H:i:s', '2012-01-24 MSK 16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-d TH:i:s', '2012-01-24 MSK16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-dT H:i:s', '2012-01-24MSK 16:53:52'));
Получаем (проверено PHP 5.3, 5.4rc6 и Trunk):
bool(false)
object(DateTime)#2 (3) {
["date"]=>
string(19) "2012-01-24 16:53:52"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}
bool(false)
object(DateTime)#3 (3) {
["date"]=>
string(19) "2012-01-24 16:53:52"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}
Похоже, это указывает на то, что идентификатор часового пояса и / или час чувствительны к пробелам ... Тестирование далее:
var_dump(\DateTime::createFromFormat('Y-m-d H:i:s', '2012-01-24 16:53:52'));
var_dump(\DateTime::createFromFormat('Y-m-dH:i:s', '2012-01-2416:53:52'));
Дает надлежащие результаты. И:
var_dump(\DateTime::createFromFormat('TY-m-d', 'MSK2012-01-24'));
var_dump(\DateTime::createFromFormat('T Y-m-d', 'MSK 2012-01-24'));
Урожайность:
bool(false)
object(DateTime)#4 (3) {
["date"]=>
string(19) "2012-01-24 01:49:26"
["timezone_type"]=>
int(2)
["timezone"]=>
string(3) "MSK"
}
Так что да, похоже, что спецификатор часового пояса чувствителен к конечным пробелам ...
Редактировать: чувствительно к пробелам
Если мы посмотрим на parse_date.c timelib_parse_from_format()
в строке 25075 , мы увидим, что все 4 формата часовых поясов анализируются одинаково! Это означает, что нет никакой разницы между идентификаторами формата для разбора, и поэтому для разбора они взаимозаменяемы.
Само по себе это кажется достаточной ошибкой (или отсутствием функции) для продолжения. Но давайте посмотрим, что происходит в timelib_get_zone()
, который вызывается при использовании идентификатора часового пояса. Ну, посмотрим, мы можем видеть, что мы вызываем timelib_lookup_zone()
, когда это не время по Гринвичу или временной сдвиг.
И там мы нашли ошибку. В строке 768 из timelib_lookup_zone
мы можем видеть, что она будет использовать всю входную строку, вплоть до \0
(ноль), )
или пробела:
while (**ptr != '\0' && **ptr != ')' && **ptr != ' ') {
++*ptr;
}
Что касается исправления, это немного сложнее. Чтобы просто решить эту проблему, потребуется повторно реализовать синтаксические анализаторы формата для каждого часового пояса. Для парсера T
это легко, так как это всегда трёхбуквенная строка. Но для других это немного интереснее, так как есть переменные буквы, и поэтому может возникнуть проблема с чувствительностью пробела.
Короче, я бы предложил просто добавить конечный пробел к вашим идентификаторам часовых поясов и покончить с этим ...