Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Некорректная работа с часовыми поясами
Форумы портала PHP.SU » PHP » Программирование на PHP » Некорректная работа с часовыми поясами

Страниц (1): [1]
 

1. varlog - 31 Мая, 2015 - 22:40:03 - перейти к сообщению
Надо отформатировать время из timestamp согласно определённому часовому поясу.
Всё хорошо работает с UTC, хорошо работает с Europe/Moscow (UTC+3), но при использовании часовых поясов UTC+1, UTC+2 результат получается ошибочным.

Тестовый код:

PHP:
скопировать код в буфер обмена
  1.  
  2. $timestamp = 1432929600;
  3.  
  4.         (new DateTime(null, new DateTimeZone("UTC"))) // UTC
  5.                 ->setTimestamp($timestamp)->format("H, i, s"),
  6.         (new DateTime(null, new DateTimeZone("Europe/Paris"))) // UTC + 1
  7.                 ->setTimestamp($timestamp)->format("H, i, s"),
  8.         (new DateTime('@' . $timestamp))
  9.                 ->setTimezone(new DateTimeZone("Europe/Paris"))->format("H, i, s"), // UTC + 1
  10.         (new DateTime(null, new DateTimeZone("Europe/Helsinki"))) // UTC + 2
  11.                 ->setTimestamp($timestamp)->format("H, i, s"),
  12.         (new DateTime(null, new DateTimeZone("Europe/Istanbul"))) // UTC + 2
  13.                 ->setTimestamp($timestamp)->format("H, i, s"),
  14.         (new DateTime(null, new DateTimeZone("Europe/Moscow"))) // UTC + 3
  15.                 ->setTimestamp($timestamp)->format("H, i, s"),  
  16.         (new DateTime(null, new DateTimeZone("Africa/Nairobi"))) // UTC + 3
  17.                 ->setTimestamp($timestamp)->format("H, i, s")  
  18. );
  19.  

Вывод:
CODE (text):
скопировать код в буфер обмена
  1.  
  2. string(10) "20, 00, 00"
  3. string(10) "22, 00, 00"
  4. string(10) "22, 00, 00"
  5. string(10) "23, 00, 00"
  6. string(10) "23, 00, 00"
  7. string(10) "23, 00, 00"
  8. string(10) "23, 00, 00"
  9.  

Как видно, у второй, третьей, четвёртой и пятой попытки результат ошибочный.
Никак не могу сообразить в чём проблема.
Тестировал и локально и в online-sandbox`ах на разных версиях PHP — результат аналогичный.
2. DeepVarvar - 31 Мая, 2015 - 22:46:00 - перейти к сообщению
Это может быть проблема пакета tzdata, если речь о никсоподобных конечно.
Обновить пакет.
А я бы еще и ntp-клиента поставил, если все так критично.
3. varlog - 31 Мая, 2015 - 22:56:38 - перейти к сообщению
Локально Mac, пакет icu4c актуальный, tzdata вроде в него входит.
Плюс тестировал на http://sandbox[dot]onlinephpfunctions[dot]com и https://ideone[dot]com — одно и то же

Беда прям.
4. LIME - 31 Мая, 2015 - 23:07:26 - перейти к сообщению
https://pecl.php.net/package/timezonedb
?
5. DeepVarvar - 31 Мая, 2015 - 23:13:34 - перейти к сообщению
LIME этж кастыль.
varlog я вообще от пыховых таймзон отказался в пользу БД-шных.

В пределах -11:59 <--> +11:59 без всяких мерзких Foo/Bar которых и список то не полный.
6. LIME - 31 Мая, 2015 - 23:15:26 - перейти к сообщению
DeepVarvar почему костыль?
Разве не нормальное обновление зон?
(Добавление)
И все операции с датавремя запросами получать или как?
7. DeepVarvar - 31 Мая, 2015 - 23:19:21 - перейти к сообщению
Ну один раз получи NOW() и на время работы скрипта используй ака time()
8. varlog - 31 Мая, 2015 - 23:27:56 - перейти к сообщению
Хм, а вот не помогло. Версия последняя — 2015.4, модуль загружен, но изменений как-то не заметно.
9. LIME - 31 Мая, 2015 - 23:33:16 - перейти к сообщению
Ха-ха Ха-ха Ха-ха
Вот мы невнимательные
Тыж сам устанавливаешь таймстамп всем
Он по utc выставляется
Чего ты хочешь добиться вообще?
10. DeepVarvar - 31 Мая, 2015 - 23:36:25 - перейти к сообщению
Ты не понял, по UTC это для примера, типа дефолт. А дальше получаешь один раз NOW() и используешь его на время жизни скрипта. Можешь вычитать, диффать, добавлять и все такое. Т.е. синхришься на таймзону БД,
11. LIME - 31 Мая, 2015 - 23:38:08 - перейти к сообщению
DeepVarvar Да я вообще не тебе
Смотри код
Он создает по таймзоне а потом меняет установив таймстамп
(Добавление)
varlog метка времени одинакова для всех зон
12. varlog - 31 Мая, 2015 - 23:55:24 - перейти к сообщению
LIME пишет:
метка времени одинакова для всех зон
Да. Я знаю, что timestamp всегда в UTC.
Задача в том, что бы взять timestamp и отформатировать его с учётом пользовательского часового пояса.

LIME пишет:
Он создает по таймзоне а потом меняет установив таймстамп
Вот только интересно, что для UTC, UTC+3, UTC+4, UTC+5, UTC+7, UTC+8, UTC+9, UTC+10 всё замечательно работает. Проблема с UTC+1, UTC+2.
13. LIME - 01 Июня, 2015 - 00:01:18 - перейти к сообщению
А ну да
Чет не то
14. Sail - 01 Июня, 2015 - 11:39:02 - перейти к сообщению
varlog, всё логично, ведь "Следует помнить, что время по UTC не переводится ни зимой, ни летом."
Сравните время в "UTC" и "GMT" для приведённого ts и, например $timestamp = 1420131600;
15. varlog - 01 Июня, 2015 - 13:38:08 - перейти к сообщению
Да, дело оказалось в DST.
Нашёл интересное решение: http://stackoverflow[dot]com/questio[dot][dot][dot]e-from-an-offset — получать DateTimeZone с фиксированным сдвигом без всякой магии.

 

Powered by ExBB FM 1.0 RC1