Europe moscow что это
Перейти к содержимому

Europe moscow что это

  • автор:

Yii Framework

совершенно случайно наткнулся на следующее — в таблицах выводится время с неправильным таймзон, несмотря на то что в системе, в бд, в пхп все прописано, и все работает, а в yii2 нет.

система centos7, php 5.6, postgresql9.4, yii2.0.3
везде установлена Europe/Moscow, сервисы перегружены для применения настроек

$date
Mon Mar 30 23:47:54 MSK 2015
$php -r ‘echo date(«Y-m-d H:i:s T»);’
2015-03-30 23:49:24 MSK
в код вставляю — тоже самое
2015-03-30 23:52:44 MSK

в конфиге Yii пробывал и внутренний и php

'formatter' => [ 'timeZone' => 'Europe/Moscow', 'dateFormat' => 'd.MM.Y', 'timeFormat' => 'H:mm:ss', //'datetimeFormat' => 'd.MM.Y HH:mm', 'datetimeFormat' => 'php:Y-m-d H:i:s', ], 

в бд, в ячейке:
2015-03-30 23:42:49.420899+03
а в таблице выводит
2015-03-31 00:42:49

откуда такое может быть ?
yii имеет свои файлы таймзон ?

upd
указал в конфиге

'datetimeFormat' => 'php:Y-m-d H:i:s T O',

2015-03-31 00:42:49 GMT+04:00
а если убрать форматирование, то выдает в таблице как и должно быть
2015-03-30 23:42:49.420899+03
yiijeka Сообщения: 3103 Зарегистрирован: 2012.01.28, 09:14 Откуда: Беларусь Контактная информация:

Re: Time zone — Europe/Moscow

Сообщение yiijeka » 2015.03.31, 08:09

в GridView по умолчанию используется Intl форматирование, для него нужно тоже указать:

'formatter' => [ 'defaultTimeZone' => 'Europe/Minsk' ], 

‘dateFormat’ и прочие форматы лучше оставить без изменений, обычно в нужном, принятом формате всё показывается само.

В таблице можно явно указать формат:

[ 'attribute'=>'value1', 'format'=>['date', 'short'] // или вместо short в формате php:d.m.Y ,что равнозначно ] 

sm-vasya Сообщения: 191 Зарегистрирован: 2015.03.04, 01:12

Re: Time zone — Europe/Moscow

Сообщение sm-vasya » 2015.03.31, 13:03

yiijeka писал(а): в GridView по умолчанию используется Intl форматирование, для него нужно тоже указать:

'formatter' => [ 'defaultTimeZone' => 'Europe/Minsk' ],

‘dateFormat’ и прочие форматы лучше оставить без изменений, обычно в нужном, принятом формате всё показывается само.

а не подскажете более точнее куда вписать это ? если в конфиг, в ‘components’ => ‘formatter’ то уже вписал

yiijeka писал(а): В таблице можно явно указать формат:

[ 'attribute'=>'value1', 'format'=>['date', 'short'] // или вместо short в формате php:d.m.Y ,что равнозначно ]

да дело собственно не в формате, а в том что часы в другом часовом поясе

mickgeek Сообщения: 957 Зарегистрирован: 2014.05.31, 20:50 Откуда: Санкт-Петербург Контактная информация:

Europe moscow что это

Yhlas_Y → Favourite problem

islamicTerrorist69 → Facing problem in dynamic programming

SilverSurge → CSES Range Queries: Polynomial Queries

127.0.0.1 → Codeforces Round 907 (Div. 2)

_thor__ → Codeloop 2023: A Knockout Tournament Based Coding Contest

Yhlas_Y → IDE for cp

MikeMirzayanov → Please, read this

Imakf → Codeforces Round 906 Editorial

noomaK → IEEEXtreme 17.0 Problems Discussion

chenjb → Rescheduling of World Finals 22&23

anmolsainiii23 → Confused Regarding Cses 2nd DP Question

-kirito- → TheForces Round #25 Editorial

stdfloat → Is CF enough for IZHO, IOI?

DeadPixel99 → Help needed!

Vladosiya → Codeforces Command Lines (2023-10-06)

-kirito- → Invitation to TheForces #25 (5^2-Forces, TheForces-Rated, Prizes!)

one_autum_leaf → Find the number of rectangles of same color in a matrix

ryuukumar → What to learn to solve 1300 rated questions?

Imakf → Codeforces Round 906 (Div. 1, Div. 2)

74TrAkToR → Codeforces Round #904 (Div. 2) Editorial

whynesspower → Reverse check the questions: ChatGPT

aryang22 → Perhaps you should wait a little before giving up.

Alpha_Info → Listen to music?

_Firdavs_Aminov_ → Dark theme Codeforces

sarthakjoleya → Need Help for my Sorting Visualizer

Блог пользователя RodionGork

Автор RodionGork, 12 лет назад ,

Некоторое время назад обнаружили что почти все машины на работе (и не только на работе) для java-программ отображают время со сдвигом на час (меньше чем надо показывают).

Для проверки можно использовать следующее:

public class ShowTime public static void main(String. args) System.out.println(new java.util.Date()); 
System.out.println(java.util.TimeZone.getTimeZone("Europe/Moscow")
.useDaylightTime());
> // main
> // class ShowTime

Выглядит результат примерно так:

rodion@rg-home:~/my/java# date
Sat Nov 26 09:01:19 MSK 2011
rodion@rg-home:~/my/java# java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode)
rodion@rg-home:~/my/java# java ShowTime
Sat Nov 26 08:01:30 MSK 2011
true
rodion@rg-home:~/my/java#

Заметьте — время в системе 9 утра, а в java — 8 утра. 😉
С чем это связано идеологически все знают. А если кто-то не знает, как это поправить практически, то можете поступить как-то так:

1) Скачать и запустить официальный апдейтер инфы о таймзонах с ораклового сайта. Вариант хорош тем, что позволяет «пофиксить» время в JVM, не обновляя её. Актуально, скажем, если на работе 50 операторских компов используют java-приложения ещё под java 1.5 и т.п.

2) Можете попробовать обновиться до Java 7u1 или 6u29 — но по-моему это не поможет. Там пакет временных зон 2011g, кажется, а в апдейтере 2011k — возможно, в этом дело.

3) Проблема не будет воспроизводиться если временная зона самой ОС кривая-московская, не обновлённая например в XP SP2. Можно конечно этим воспользоваться. 😉

P.S. Буду признателен, если сообщите на каких комбинациях OS/JVM у вас найдётся эта проблема. Я фиксил только на Windows/Linux и только 7u0, 7u1, 6u27.

Теги

java, timezone

Записки программиста

Часовые пояса обычно ассоциируются с чем-то невероятно сложным. Однако, как это часто бывает, если сесть и спокойно во всем разобраться, то проблема оказывается не такой уж большой. Особенно если положиться на проверенные решения, где уже реализована вся логика.

PostgreSQL предлагает два типа для хранения даты и времени — timestamp и timestamptz. Внутреннее представление данных типов абсолютно одинаковое. Это 64-х битные знаковые целые, хранящие время в микросекундах относительно 1-го января 2000-го года 00:00:00 UTC.

Отличие только в том, как они отображаются:

С timestamp все понятно, это же просто время в UTC. Однако timestamptz отображается в часовом поясе текущей сессии:

=# show time zone;
TimeZone
—————
Europe/Moscow

=# select ‘2021-10-01 12:34:56 Europe/Moscow’ :: timestamptz;
timestamptz
————————
2021-10-01 12:34:56+03

=# set time zone ‘+00’;
SET

=# select ‘2021-10-01 12:34:56 Europe/Moscow’ :: timestamptz;
timestamptz
————————
2021-10-01 09:34:56+00

Еще раз, ключевой момент — значение одно и то же! Но отображается оно по-разному в зависимости от параметров сессии.

Часовой пояс, используемый по умолчанию, определяется параметром timezone в файле postgresql.conf. Этот параметр прописывается утилитой initdb во время инициализации СУБД. Значение параметра определяется окружением, в котором был запущен initdb. Если параметр не указан в postgresql.conf, используется часовой пояс GMT.

Получить информацию о доступных именах часовых поясов можно так:

=# select * from pg_timezone_names where abbrev = ‘MSK’;
name | abbrev | utc_offset | is_dst
——————-+———+————+———
Europe/Moscow | MSK | 03:00:00 | f
Europe/Simferopol | MSK | 03:00:00 | f
W-SU | MSK | 03:00:00 | f

Отсюда мы узнаем, что для Europe/Moscow есть сокращение MSK. Сокращения можно использовать при преобразовании строки в timestamptz:

=# select ‘2021-10-01 12:34:56 MSK’ :: timestamptz;
timestamptz
————————
2021-10-01 12:34:56+03

Но команда set time zone принимает только полное имя часового пояса:

=# set time zone ‘MSK’;
ERROR: invalid value for parameter «TimeZone»: «MSK»

=# set time zone ‘Europe/Moscow’;
SET

Иногда нужно преобразовать timestamptz в timestamp или наоборот. Если делать это в лоб, то результат может получиться не тот, который вы ожидаете:

=# set time zone ‘+00’;
SET

=# select (‘2021-10-01 12:34:56 MSK’ :: timestamptz) :: timestamp;
timestamp
———————
2021-10-01 09:34:56

Как же так? Ведь я хотел отрезать информацию о таймзоне и получить 12:34:56! Но вспомним, что внутри timestamptz хранится просто как время в UTC. В момент, когда timestamptz кастуется в timestamp у PostgreSQL нет никакой возможности узнать, что изначально время было в Europe/Moscow. Поэтому он преобразует время в часовой пояс текущий сессии.

Домашнее задание: Вызовите now() и now() :: timestamp . Смените часовой пояс сессии и повторите эксперимент. Объясните результат.

Для решения описанной проблемы есть альтернативный синтаксис:

=# select (‘2021-10-01 12:34:56 Europe/Moscow’ :: timestamptz) ⏎
at time zone ‘Europe/Moscow’;
timezone
———————
2021-10-01 12:34:56

Или, что полностью эквивалентно, можно воспользоваться функцией timezone:

=# select timezone(‘Europe/Moscow’, ⏎
‘2021-10-01 12:34:56 Europe/Moscow’ :: timestamptz);
timezone
———————
2021-10-01 12:34:56

Для преобразования в обратную сторону есть перегруженная версия timezone, принимающая timestamp и возвращающая timestamptz:

=# set time zone ‘Europe/Moscow’;
SET

=# select timezone(‘Europe/Moscow’, ‘2021-10-01 12:34:56’ :: timestamp);
timezone
————————
2021-10-01 12:34:56+03

Синтаксис at time zone также работает для timestamp:

=# select (‘2021-10-01 12:34:56’ :: timestamp) ⏎
at time zone ‘Europe/Moscow’;
timezone
————————
2021-10-01 12:34:56+03

Когда вы работаете в UTC или каком-нибудь UTC+3, все просто и понятно. Но при использовании часового пояса вроде MSK все интереснее. Вот пример:

=# set time zone ‘Europe/Moscow’;
SET

=# select (timestamptz ‘2014 Oct 26 01:00:00 MSK’);
timestamptz
————————
2014-10-26 01:00:00+03

=# select (timestamptz ‘2014 Oct 26 01:00:00 MSK’) — interval ‘1 hour’;
?column?
————————
2014-10-26 01:00:00+04

Был час ночи. Отняли один час, и получили час ночи. Удобно, не правда ли?

Дело в том, что московское время несколько раз менялось в прошлом, и наверняка еще изменится в будущем. 26 октября 2014-го года часовой пояс MSK как раз изменился с UTC+4 на UTC+3, о чем PostgreSQL прямым текстом и говорит — обратите внимание на +03 и +04 в выводе. Аналогичные приколы вас ждут в часовых поясах, где есть перевод часов на летнее и зимнее время (daylight saving time, DST). В Москве сейчас не переводят часы, но до марта 2011-го года переводили.

Fun fact! Если у времени в конкретном часовом поясе могут быть «дырки», то как timezone(zone, timestamp) обрабатывает невозможное время, попадающие в эти «дырки»? В данном сценарии функция завершается успешно, при этом невозможное время преобразуется в ближайшее возможное.

Для timestamptz из прошлого PostgreSQL применяет правила для часового пояса, которые были актуальны на тот момент времени. Приведенный выше пример наглядно это демонстрирует. Другими словами, если сейчас в вашем часовом поясе время T, оно всегда будет временем T в этом часовом поясе, даже если в будущем правила изменятся. Для времени из будущего применяются последние известные правила. Это означает, что при обновлении PostgreSQL и/или системы могут появится новые правила для часовых поясов, и функции, использующие timestamptz, начнут возвращать другой результат. Впрочем, это касается не только времени из будущего. Также были прецеденты исторических корректировок часовых поясов.

Несмотря на написанное выше, volatility функций, работающих с timestamptz, не обязательно является STABLE. В качестве STABLE-функции, работающей с timestamptz, можно привести в пример date_trunc() . Дело в том, что ее работа зависит от параметров сессии. Кастинг timestamptz в timestamp является STABLE по той же причине. Однако функция timezone() не смотрит на параметры сессии. Ее возвращаемое значение зависит только от переданных аргументов, и потому функция является IMMUTABLE. PostgreSQL не будет возражать, если вы решите использовать ее в функциональных индексах. И при обновлении базы часовых поясов индексы могут разъехаться.

Fun fact! PostgreSQL имеет собственную базу часовых поясов. В исходном коде эта база называется tzdata.zi. Но также PostgreSQL можно собрать с флагом —with-system-tzdata= . Он говорит использовать вместо собственной базы системные TZif-файлы (RFC 8536) . Эти файлы обычно живут в /usr/share/zoneinfo. Чтобы узнать, какую базу использует PostgreSQL, нужно проверить, с какими флагами был собран используемый вами пакет. Эти флаги отображает команда pg_config —configure .

Все перечисленное важно понимать для решения практических задач.

Допустим, вам нужно строить агрегаты по дням или месяцам в конкретном часовом поясе. Оказывается, что самое простое и надежное решение — это преобразовать время в timestamp при помощи at time zone , и затем обращаться с timestamp как с обычным временем. Если нужно несколько часовых поясов, строим несколько агрегатов. Здесь предполагается, что вы не работаете с временем из далекого будущего и своевременно обновляетесь. В противном случае агрегаты рано или поздно сломаются, и починить их сможет только перестройка из сырых данных. Хранить последние — всегда хорошая мысль, как минимум, потому что требования к системе меняются, и возникает необходимость в новых агрегатах. Ну и баги в коде никто не отменял.

Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.

Ручное обновление базы данных часовых поясов в старых дистрибутивах Линукс

Все может быть, что данная заметка пригодится тем суркам-администраторам, которые до сих пор (о, ужас!) не перевели системные часы своих серверов, позволив умным машинам установить зимнее время. Да, конечно, мы-то с Вами к таким не относимся и вовремя пропатчили свою любимую ОС, под которой крутится успешно не один сайт.

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

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

Ручное обновление приводится на примере дистрибутива Линукс Fedora 8 (думаю, пример будет также применим и к дистрибутивам Red Hat и CentOS). Именно под этой системой трудится веб-сервер на одной из машин, за которой я присматриваю.

Итак, логинимся под обыкновенным пользователем по SSH и смотрим текущее время (оно берется из файла /etc/localtime) и, сразу же, текущий установленный часовой пояс:

[user@server ~]$ date Fri Nov 18 18:59:57 MSK 2011 [user@server ~]$ cat /etc/sysconfig/clock | grep ZONE ZONE="Europe/Moscow"

Здесь мы машинально смотрим на свои «соломенные», видим отставание на один час и тут же проверяем был ли осуществлен переход на зимнее время наверняка:

[user@server ~]$ zdump -v /etc/localtime | grep 2011 Europe/Moscow Sat Mar 26 22:59:59 2011 UTC = Sun Mar 27 01:59:59 2011 MSK isdst=0 gmtoff=10800 Europe/Moscow Sat Mar 26 23:00:00 2011 UTC = Sun Mar 27 03:00:00 2011 MSD isdst=1 gmtoff=14400 Europe/Moscow Sat Oct 29 22:59:59 2011 UTC = Sun Oct 30 02:59:59 2011 MSD isdst=1 gmtoff=14400 Europe/Moscow Sat Oct 29 23:00:00 2011 UTC = Sun Oct 30 02:00:00 2011 MSK isdst=0 gmtoff=10800 

Строки с октябрьской датой подтверждают факт ненужного теперь перевода на зимнее время (подробный пост про это сделал хабрапользователь GreyCat).

Чтобы поправить ситуацию идем на сайт IANA (The Internet Assigned Numbers Authority) — именно там теперь публикуются обновленные файлы The Time Zone Database (базы данных временных поясов известную также среди сисадминов как tz database или zoneinfo database) и скачиваем файл tzdata, содержащего последние обновления. Для скачивания удобней воспользоваться утилитами наподобие wget или curl (что найдется под рукой), а не браузером:

[user@server ~]$ wget http://www.iana.org/time-zones/repository/releases/tzdata2011n.tar.gz
[user@server ~]$ curl -O www.iana.org/time-zones/repository/releases/tzdata2011n.tar.gz

Тут же распакуем содержимое скачанного файла tzdata (можно в тот же каталог, куда скачали):

[user@server ~]$ tar xzf tzdata2011n.tar.gz

И, наконец, самое главное.
Компилируем файл временных поясов europe в бинарный вид и тут же делаем ключевой файл /etc/localtime символической ссылкой на соответствующий поясу файл (в данном случае пояс Europe/Moscow), иначе система не узнает о том, что мы обновили содержимое базы.

Данная команда потребует прав суперпользователя, поэтому исполнять ее нужно от имени root:

[root@server user]$ zic europe [root@server user]$ ln -sf --suffix=.backup /usr/share/zoneinfo/Europe/Moscow /etc/localtime

На этом — всё! Смотрим время, теперь выводится все правильно:

[root@server user]$ date Fri Nov 18 20:14:37 MSK 2011

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *