LINUX.ORG.RU

PHP - что-то не так с зонами и временем

 ,


0

1

Обнаружил интересную штуку:

> date 
Втр Июл  1 23:11:55 MSK 2014

> php -r "$d = DateTime::createFromFormat('Y.m.d H:i:s T', '2014.07.01 23:11:55 MSK'); echo $d->format(DateTime::W3C) . PHP_EOL;"
2014-07-01T23:11:55+03:00

> php -r "$d = new DateTime('now', new DateTimeZone('MSK')); echo $d->format(DateTime::W3C) . PHP_EOL;"                          
2014-07-01T23:12:57+04:00

Интересно тут вот что: 2014-07-01T23:11:55+03:00 2014-07-01T23:12:57+04:00

Т.е. при получении текущего времени в зоне MSK, смещение времени определяется верно (+04:00), а при создании времени из зоны MSK, смещение определяется не верно (+03:00).

Или я что-то неправильно понимаю?

P.S. Debian Wheezy с обновленным tzdata из wheezy/updates.

На Jessie получается вообще вот так:

> php -r "\$d = new DateTime('now', new DateTimeZone('MSK')); echo \$d->format(DateTime::W3C) . PHP_EOL;"          
2014-07-01T22:20:55+03:00
★★

Тут верно?

# dpkg-reconfigure tzdata

Current default time zone: 'Europe/Moscow'
Local time is now:      Wed Jul  2 18:37:21 MSK 2014.
Universal Time is now:  Wed Jul  2 14:37:21 UTC 2014.
quest ★★★★ ()

Выглядит как баг. У меня куча ругани в консоле, ежель юзать createFromFormat без явной timezone

alf@xxx-dev:~$ php -r "echo DateTime::createFromFormat(DateTime::RFC850, 'Monday, 15-Aug-13 15:52:01 MSK')->format(DateTime::W3C) . PHP_EOL;"
PHP Warning:  DateTime::createFromFormat(): 
It is not safe to rely on the system's timezone settings. 
You are *required* to use the date.timezone setting or the date_default_timezone_set() function. 
In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. 
We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Command line code on line 1
2013-08-19T15:52:01+03:00
alf@xxx-dev:~$ php -r "echo DateTime::createFromFormat(DateTime::RFC850, 'Monday, 15-Aug-13 15:52:01 MSK')-> setTimezone(new DateTimeZone('MSK'))->format(DateTime::W3C) . PHP_EOL;"
PHP Warning:  DateTime::createFromFormat(): 
It is not safe to rely on the system's timezone settings. 
You are *required* to use the date.timezone setting or the date_default_timezone_set() function. 
In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. 
We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Command line code on line 1
2013-08-19T16:52:01+04:00

vtVitus ★★★★★ ()
Ответ на: комментарий от quest

Да:

> sudo dpkg-reconfigure tzdata

Current default time zone: 'Europe/Moscow'
Local time is now:      Thu Jul  3 13:53:16 MSK 2014.
Universal Time is now:  Thu Jul  3 09:53:16 UTC 2014.
SaBo ★★ ()
Ответ на: комментарий от swwwfactory

Если я правильно, понимаю, date.timezone устанавливает временную зону по умолчанию. У меня проблема в неправильном конвертировании времени с уже установленной таймзоной.

> php -r "var_dump(ini_get('date.timezone'));"
string(0) ""
SaBo ★★ ()
Последнее исправление: SaBo (всего исправлений: 1)
Ответ на: комментарий от vtVitus

Выглядит как баг. У меня куча ругани в консоле, ежель юзать createFromFormat без явной timezone

Видимо, нужно идти на bugs.php.net. Спасибо, за пример.

SaBo ★★ ()
Ответ на: комментарий от vtVitus

У меня куча ругани в консоле, ежель юзать createFromFormat без явной timezone

Это, кстати, правильно. Если в php.ini не установить часовой пояс по умолчанию, то php будет выкидывать варненги.

А вот проблема со смещением времени у вас остаётся как и у меня.

SaBo ★★ ()
Ответ на: комментарий от SaBo
$ php -r "var_dump(ini_get('date.timezone'));"
string(13) "Europe/Moscow"

Пропиши во все php.ini в секцию [Date]:

date.timezone = Europe/Moscow
и перепусти сервер. по умолчанию там закомментированная пустота

quest ★★★★ ()
Последнее исправление: quest (всего исправлений: 1)
Ответ на: комментарий от quest

Это не помогает (и, видимо, не поможет, т.к. проблема в другом).

> php -r "ini_set('date.timezone', 'Europe/Moscow'); var_dump(ini_get('date.timezone')); $d = DateTime::createFromFormat('Y.m.d H:i:s T', '2014.07.01 23:11:55 MSK'); echo $d->format(DateTime::W3C) . PHP_EOL;"

string(13) "Europe/Moscow"
2014-07-01T23:11:55+03:00
SaBo ★★ ()
Ответ на: комментарий от SaBo

Следует избегать «пустого значения» date.timezone.

Выстави в php.ini или программно какую-нибудь зону по умолчанию и все д.б. ок. И подними уровень ошибок до макси.

swwwfactory ★★ ()
Последнее исправление: swwwfactory (всего исправлений: 1)
Ответ на: комментарий от swwwfactory

Хорошо :) Я благодарю вас за то, что пытаетесь мне помочь, но проблема не в зоне по умолчанию, а в неправильном смещении времени при уже установленной таймзоне (которая берется из строки с датой).

error_reporting = E_ALL 
display_errors = On
display_startup_errors = On

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Europe/Moscow

Проблема осталась:

> php -r "var_dump(ini_get('date.timezone')); $d = DateTime::createFromFormat('Y.m.d H:i:s T', '2014.07.01 23:11:55 MSK'); echo $d->format(DateTime::W3C) . PHP_EOL;"
string(13) "Europe/Moscow"
2014-07-01T23:11:55+03:00

> php -r "var_dump(ini_get('date.timezone')); $d = new DateTime('now', new DateTimeZone('MSK')); echo $d->format(DateTime::W3C) . PHP_EOL;"
string(13) "Europe/Moscow"
2014-07-03T15:34:53+04:00
SaBo ★★ ()
Ответ на: комментарий от SaBo
$ cat test.php 
<?php

$now = time();

echo date("'Y.m.d H:i:s O", $now)."\n";
echo gmdate("'Y.m.d H:i:s O", $now)."\n";

?>
$ php -f test.php 
'2014.07.03 15:42:36 +0400
'2014.07.03 11:42:36 +0000

что еще нужно?

quest ★★★★ ()
Ответ на: комментарий от quest

Нужно парсить дату/время с указанным временным поясом.
У меня нет гарантий, что дата не придёт с другим часовым поясом.

SaBo ★★ ()
Ответ на: комментарий от quest

Поясню: в ответе от стороннего сервера ко мне приходит дата в формате Y.m.d H:i:s T. Например: «2014.07.01 23:11:55 MSK».
Но у меня нет гарантий, что не придёт что-то вроде «2014.07.01 23:11:55 WET»

SaBo ★★ ()
Ответ на: комментарий от quest

Ну вообще можно и без unixtime'а обойтись, т.к. вот это:

> php -r "$d = DateTime::createFromFormat('Y.m.d H:i:s', '2014.07.01 23:11:55', new DateTimeZone('MSK')); echo $d->format(DateTime::W3C) . PHP_EOL;"
2014-07-01T23:11:55+04:00

работает верно. Но хотелось бы разобраться в причинах ошибки.

SaBo ★★ ()
Последнее исправление: SaBo (всего исправлений: 1)
Ответ на: комментарий от SaBo

ok, просто я DateTime вообще не юзал, хватало и date()/time()

quest ★★★★ ()
Ответ на: комментарий от SaBo
the@host ~ $ php -r "var_dump(ini_get('date.timezone')); \$d = new DateTime('now', new DateTimeZone('MSK')); echo \$d->format(DateTime::W3C) . PHP_EOL;"
string(13) "Europe/Moscow"
2014-07-03T16:01:14+03:00

the@host ~ $ php -r "var_dump(ini_get('date.timezone')); \$d = DateTime::createFromFormat('Y.m.d H:i:s T', '2014.07.01 23:11:55 MSK'); echo \$d->format(DateTime::W3C) . PHP_EOL;"
string(13) "Europe/Moscow"
2014-07-01T23:11:55+03:00
swwwfactory ★★ ()
Ответ на: комментарий от swwwfactory

Интересно, спасибо.
Версия php/ОС какие?

На Debian Jessie такие же результаты.

Либо зону MSK подготовили к осеннему переводу времени либо я вообще не понимаю, почему смещение времени +3 часа.

SaBo ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.