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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Некорректная работа с часовыми поясами

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
varlog
Отправлено: 31 Мая, 2015 - 22:40:03
Post Id


Новичок


Покинул форум
Сообщений всего: 5
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




Надо отформатировать время из 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 — результат аналогичный.
 
 Top
DeepVarvar Супермодератор
Отправлено: 31 Мая, 2015 - 22:46:00
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Это может быть проблема пакета tzdata, если речь о никсоподобных конечно.
Обновить пакет.
А я бы еще и ntp-клиента поставил, если все так критично.
 
 Top
varlog
Отправлено: 31 Мая, 2015 - 22:56:38
Post Id


Новичок


Покинул форум
Сообщений всего: 5
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




Локально Mac, пакет icu4c актуальный, tzdata вроде в него входит.
Плюс тестировал на http://sandbox[dot]onlinephpfunctions[dot]com и https://ideone[dot]com — одно и то же

Беда прям.
 
 Top
LIME
Отправлено: 31 Мая, 2015 - 23:07:26
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




 
 Top
DeepVarvar Супермодератор
Отправлено: 31 Мая, 2015 - 23:13:34
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




LIME этж кастыль.
varlog я вообще от пыховых таймзон отказался в пользу БД-шных.

В пределах -11:59 <--> +11:59 без всяких мерзких Foo/Bar которых и список то не полный.
 
 Top
LIME
Отправлено: 31 Мая, 2015 - 23:15:26
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




DeepVarvar почему костыль?
Разве не нормальное обновление зон?
(Добавление)
И все операции с датавремя запросами получать или как?
 
 Top
DeepVarvar Супермодератор
Отправлено: 31 Мая, 2015 - 23:19:21
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Ну один раз получи NOW() и на время работы скрипта используй ака time()
 
 Top
varlog
Отправлено: 31 Мая, 2015 - 23:27:56
Post Id


Новичок


Покинул форум
Сообщений всего: 5
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




Хм, а вот не помогло. Версия последняя — 2015.4, модуль загружен, но изменений как-то не заметно.

(Отредактировано автором: 31 Мая, 2015 - 23:28:49)

 
 Top
LIME
Отправлено: 31 Мая, 2015 - 23:33:16
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




Ха-ха Ха-ха Ха-ха
Вот мы невнимательные
Тыж сам устанавливаешь таймстамп всем
Он по utc выставляется
Чего ты хочешь добиться вообще?
 
 Top
DeepVarvar Супермодератор
Отправлено: 31 Мая, 2015 - 23:36:25
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Ты не понял, по UTC это для примера, типа дефолт. А дальше получаешь один раз NOW() и используешь его на время жизни скрипта. Можешь вычитать, диффать, добавлять и все такое. Т.е. синхришься на таймзону БД,
 
 Top
LIME
Отправлено: 31 Мая, 2015 - 23:38:08
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




DeepVarvar Да я вообще не тебе
Смотри код
Он создает по таймзоне а потом меняет установив таймстамп
(Добавление)
varlog метка времени одинакова для всех зон
 
 Top
varlog
Отправлено: 31 Мая, 2015 - 23:55:24
Post Id


Новичок


Покинул форум
Сообщений всего: 5
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




LIME пишет:
метка времени одинакова для всех зон
Да. Я знаю, что timestamp всегда в UTC.
Задача в том, что бы взять timestamp и отформатировать его с учётом пользовательского часового пояса.

LIME пишет:
Он создает по таймзоне а потом меняет установив таймстамп
Вот только интересно, что для UTC, UTC+3, UTC+4, UTC+5, UTC+7, UTC+8, UTC+9, UTC+10 всё замечательно работает. Проблема с UTC+1, UTC+2.
 
 Top
LIME
Отправлено: 01 Июня, 2015 - 00:01:18
Post Id


Активный участник


Покинул форум
Сообщений всего: 10732
Дата рег-ции: Нояб. 2010  


Помог: 322 раз(а)




А ну да
Чет не то
 
 Top
Sail
Отправлено: 01 Июня, 2015 - 11:39:02
Post Id



Участник


Покинул форум
Сообщений всего: 1131
Дата рег-ции: Февр. 2014  


Помог: 57 раз(а)




varlog, всё логично, ведь "Следует помнить, что время по UTC не переводится ни зимой, ни летом."
Сравните время в "UTC" и "GMT" для приведённого ts и, например $timestamp = 1420131600;
 
 Top
varlog
Отправлено: 01 Июня, 2015 - 13:38:08
Post Id


Новичок


Покинул форум
Сообщений всего: 5
Дата рег-ции: Май 2015  


Помог: 0 раз(а)




Да, дело оказалось в DST.
Нашёл интересное решение: http://stackoverflow[dot]com/questio[dot][dot][dot]e-from-an-offset — получать DateTimeZone с фиксированным сдвигом без всякой магии.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Программирование на PHP »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB