![]() |
#1 |
Участник
|
axforum blogs: TimeZone в Ax2009
Источник: http://axforum.info/forums/blog.php?b=8150
============== Редкий случай, когда задачу на модификацию в Axapta поставили ДО вступления в силу очередного постановления правительства. Обычно задачу ставят спустя пол-года..год ПОСЛЕ ;). В данном случае, постановление о переводе часов на один час назад 26.10.2014 в 2 часа ночи. Ну, поскольку "ждать милостей от ..." не приходится, то решил разобраться самостоятельно Импорт новых правил определения часовых поясов - это форма TimezonePatchImport. В ней выбирается файл XML, который формирует новую запись в таблице \System Documentation\Tables\TimeZonesRulesData. Ага. И как должен выглядеть этот файл для новых правил? Ну, для начала надо понять назначение полей таблицы TimeZonesRulesData. Как оказалось, это не такая очевидная вещь :) Единственная ссылка, которую нашел http://stackoverflow.com/questions/1...ersion/1293263 По этой ссылке (и после ряда экспериментов ;) ) разобрался в назначении полей ---------------------------------------------------------- Назначение полей таблицы \System Documentation\Tables\TimeZonesRulesData RULEID - идентификатор записи. Фассетный код: первые 2 символа - значение поля TZENUM, далее 3 символа - порядковый номер TZENUM: Внешний ключ ссылки на таблицу TIMEZONESLIST или значение Base Enum: \System Documentation\Enums\Timezone YEAR: 0 если правило действует бессрочно или год применения правила BIAS: сдвиг времени в минутах относительно времени UTC DBIAS: периодический сдвиг DST (добавляется к BIAS для установки общего сдвига от UTC) Поля D* - определят начальную дату и время для сдвига DST Поле S* - определят конечную дату и время для сдвига DST Смысл полей ясен из их имени, кроме полей *DAY DDAY и SDAY - это номер недели в месяце (1-4, 5 = последняя неделя) DDAYOFWEEK и SDAYOFWEEK - номер дня недели (0 = Воскресенье) Необходимо либо задавать диапазон (как начальные, так и конечные даты), либо не задавать диапазон вообще. Указать только начальную или только конечную дату - невозможно. Это будет расценено как отсутствие диапазона. Т.е. действует на весь год ---------------------------------------------------------- Вот по какой логике в поле с названием DAY записывается номер недели в месяце? "Загадочная датская душа", не иначе :D Или уже американская :cool: Кстати, и файл XML за 2010..2011 года тоже "чудо чудное". Начало диапазона тогда задали в октябре, а окончание в мае. Ну, вероятно, спиной к монитору программировали :) ---------------------------------------------------------- Ну, тогда новый файл XML получается таким PHP код: 61004 61 2014 -240 0 10 0 5 2 0 0 60 0 12 3 5 23 59 59 0 61005 61 2015 -180 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 В принципе, можно сделать и одну запись, поставив в качестве даты окончания 2153 год. Но надо учитывать, что наше родное правительство в любой момент может выпустить очередное постановление о "самом правильном" распределении часовых поясов. О здоровье граждан они уже побеспокоились, следующее постановление замотивируют экономическим соображениями :D Источник: http://axforum.info/forums/blog.php?b=8150
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
![]() |
#2 |
Участник
|
axforum blogs: TimeZone в Ax2009
Источник: http://axforum.info/forums/blog.php?b=8151
============== Ну, хорошо, новое правило определения TimeZone добавили. А что делает форма TimeZonePatcher? О каких таких "исправлениях" идет речь? Для начала, надо разобраться с "физикой" процесса ;) При создании полей на основе базового типа данных Types::UtcDateTime физически, на уровне базы данных создаются 2 поля: 1. Поле с типом DateTime хранящее время UTC 2. Поле, имя которого совпадает с именем поля DateTime, но с добавленным окончанием "TZID". Поле *TZID является служебным и не отображется в среде Axapta. Хотя в таблице SqlDictionary присутствуют. Например, в таблице BatchJob есть поле OrigStartDateTime, которое видно в списке полей этой таблицы в AOT. Но, кроме того, у этой же таблицы есть поле OrigStartDateTimeTZID, которое можно увидеть только на уровне базы данных SQL. В среде Axapta оно не видно В поле *TZID записывается идентификатор временной зоны (TZID = Time Zone IDentifier). Таким идентификатором является значение поля таблицы TimeZonesRulesData.RuleID Таблица TimeZonesRulesData это правила, определяющие "сдвиг" в минутах, который надо добавить (или вычесть) к значению поля DateTime Логика чтения полей DateTime выглядит так: 1. Из поля DateTime считывается значение 2. Из поля *TZID считывается идентификатор правила чтения временных зон, определяется "сдвиг" в минутах и прибавляется к значению DateTime Исключением из этого правила являются поля CreatedDateTime и ModifiedDateTime. Им в пару не создаются поля *TZID. Т.е. при их считывании всегда используется текущее правило "сдвига" времени в минутах. Причина, по которой возникает необходимость "патчить" данные - это тот факт, что поле *TZID заполняется один раз в момент создания записи и больше уже не изменяется на протяжении всего времени существования записи. Это значит, что если, например, до импорта новых правил определения временных зон Вы создадите пакетное задание, плановое дата/время которого будет, скажем, 01.11.2014 01:00:00, то, после импорта новых правил будет отображаться значение 01.11.2014 02:00:00. Почему? Да потому, что поле *TZID останется без изменений и будет ссылаться на правила расчета 2011 года. Т.е. добавлять к времени UTC (то, что сохранено в базе данных в поле DateTime) 4 часа, а не 3, как должно быть по новым правилам. Следовательно, необходимо для всех дат, которые попали в область действия новых правил определения временных зон сделать замену: 1. В поле *TZID записать код записи нового правила 2. Поле DateTime увеличить на 1 час Зачем добавлять 1 час? Так в базе данных записано время UTC. Т.е. без сдвига на 4 часа там хранится время 31.10.2014 21:00:00. Если к этому времени добавить 3 часа по новым правилам, то получим 01.11.2014 00:00:00, вместо ожидаемого 1 часа. Вот чтобы поясное время не изменилось, время UTC и надо увеличить на 1 час Собственно, именно этим и занимается форма TimeZonePatcher. После открытия этой формы надо выбрать обновляемое правила из списка (этот список заполняется и обновляется при импорте файла XML) и нажать кнопку "Загрузить все затронутые поля UtcDateTime". Этот процесс займет некоторое время (несколько минут), поскольку связан с перебором всех таблиц и определения факта наличия в них полей на базе UtcDateTime. После того, как в нижней части формы отобразится список полей таблиц, Вам надо выбрать те поля, который Вы будете обновлять и нажать кнопку "Применить исправление" -------------------------------------------------------- Ну, вроде все хорошо? "Счаззз"... У нас же обязательно какая-нибудь проблема вылезет ;) Проблема заключается в том, что исправляются только те данные, которые попадают в область действия новых правил. В отношении правила 2014 года это не критично, поскольку он уже наступил. Просто импортируем файл XML с новыми правилами и запускаем форму TimeZonePatcher ДО наступления 26.10.2014 года. А вот с правилом 2015 года - есть проблема. Если у Вас работают пакетные задания, то 01.01.2015 00:00:00 у всех них произойдет сдвиг запланированного времени исполнения на 1 час вперед. Почему? Так ведь у них по прежнему будет указан код *TZID относящийся к 2014 году. Как следствие, в январе сдвиг будет составлять 4 часа, а не 3 как необходимо. Если для Вас сдвиг выполнени пакетных задний на 1 час не критичен, то этим можно пренебречь и выполнить запуск формы TimeZonePatcher после новогодних каникул 12 января. Если же это является проблемой, то следует поступить следующим образом: 1. В 2014 году импортируется только 1 правило, действующее с 26 октября 2014 кода и по 2153 год. Это импорт такого файла XML PHP код: 61004 61 2014 -240 0 10 0 5 2 0 0 60 2153 12 3 5 23 59 59 0 Отличие от первоначального вариант - это тег 2153. Это значит, что 26.10.1014 произойдет сдвиг на 1 час вперед, но перевод на 1 час назад произойдет только в 2153 году. Т.е. в 2015 году по прежнему будет работать сдвиг на 3 часа. 2. После наступления 2015 года в любое удобное время необходимо на уровне SQL-сервера выполнить замену PHP код: update TimeZonesRulesData set DYear = 0 where TzEnum = 61 and RULEID = 61004 и в Axapta импортировать файл XML с правилом на 2015 год PHP код: 61005 61 2015 -180 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3. После перезагрузки AOS запустить форму TimeZonePatcher для 2015 года Источник: http://axforum.info/forums/blog.php?b=8151
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
|
За это сообщение автора поблагодарили: d_alexe (1). |
![]() |
#3 |
Участник
|
Во общем сделал, как здесь написано.
Пересоздал пакетные задания, однако происходит периодический сдвиг на 1час вперед задания. При чем периодичность странная. то есть день ни чего через день может сдвинуть потом не сдвигает, через день опять сдвиг. ПС MSDax2009 - ru5 |
|
![]() |
#4 |
Участник
|
А как вы настроили "каждый день"? не может ли сдвигаться время следующего запуска из-за задержки запуска текущего?
__________________
Ivanhoe as is.. |
|
![]() |
#5 |
Участник
|
Вот так настроено
http://axforum.info/forums/attachmen...1&d=1416815497 ПС Данные пакеты запущены через "Запуск компьютера в качестве сервера обработки пакетных заданий." Последний раз редактировалось d_alexe; 24.11.2014 в 10:55. |
|
![]() |
#6 |
Участник
|
Время запуска пакетного задания - это UTC время, физически записанное в поле "Запланированный дата/время начала" пакетного задания (BatchJob.OrigStartDateTime), а временная зона определяется по значению поля "Рекомендуемая временная зона" в настройках того пользователя, от имени которого выполняется запуск пакетного задания(UserInfo.preferredTimeZone).
После запуска пакетного задания, следующее запланированное время запуска определяется с учетом временной зоны, указанной в настройках повторения пакетного задания. Т.е. Вам надо проверить настройку временной зоны в следующих местах 1. У себя самого 2. У того пользователя, от имени которого запускается пакетное задание (BatchJob.CreatedBy) 3. В настройках повтора пакетного задания Все 3 настройки должны совпадать. Наиболее вероятная причина проблемы - это запуск пакетного задания от имени разных пользователей. У одного временная зона настроена корректно, а у другого - нет Хотя, конечно, у Вас может быть так своеобразно настроен график работы сервера пакетной обработки. PS: Кстати, у Вас случайно AOS в это время не перезагружаются?
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... Последний раз редактировалось Владимир Максимов; 24.11.2014 в 16:20. |
|
![]() |
#7 |
Участник
|
Все оказалось банальнее, это делать нужно для каждой компании.
|
|
![]() |
#8 |
Участник
|
а нет рано обрадовался
![]() из-за чего такое может быть http://axforum.info/forums/attachmen...1&d=1418034045 время в LoginDateTime и время в статусбаре? Пример BatchJob ORIGSTARTDATETIME ORIGSTARTDATETIMETZID STARTDATETIME STARTDATETIMETZID ENDDATETIME ENDDATETIMETZID CREATEDDATETIME 2014-11-07 16:00:00.000 61004 1900-01-01 00:00:00.000 37001 1900-01-01 00:00:00.000 37001 2013-07-16 06:51:36.000 2014-08-28 07:25:33.000 61004 2014-08-28 07:26:34.000 37001 2014-08-28 07:55:12.000 37001 2014-08-28 07:25:38.000 то что в полях STARTDATETIMETZID, ENDDATETIMETZID стоит правило для Гринвича(код 37001) так и должно быть? и кстати в таблице SYSCLIENTSESSIONS картинка выше приложена в поле LOGINDATETIMETZID тоже код 37001 Последний раз редактировалось d_alexe; 08.12.2014 в 14:40. |
|
|
|