Изменения часовых поясов в России. Год 2014. Анализ обновления KB2998527.


Про заблуждения написано отдельно Изменения часовых поясов в России. Год 2014. Факты.

Теперь про обновление KB2998527.

В чём его технический смысл? Давайте посмотрим на примере одного часового пояса Russian Standard Time.

Вот запись в реестре до установки обновления:

А вот после:

Как видите было UTC+4, стало UTC+3. Но время при этом у нас на компьютере отображается то же самое, что и до установки обновления – скачка нет. К тому же в 2 часа 26 октября должен произойти автоматический перевод часов на один час назад.

Как же всё это сделано? Есть единственный механизм в ОС, который может сделать автоматический перевод времени – это перевод времени «зима-лето». Этот механизм работал на наших компьютерах многие годы.

С технической точки зрения обновление KB2998527 переводит время на час назад в соответствии с новым часовым поясом и одновременно включает переход на летнее время, переводя время на час вперед; кроме этого устанавливает автоматический переход на зимнее время в 2 часа 26 октября на один час назад.

Не верите? Давайте посмотрим. Возьмём три времени в UTC: 10 января 5 часов утра, 10 июня 5 часов утра и 29 ноября 5 часов утра – и посмотрим за разные годы локальное время.

До установки обновления:

year a b c

—- — — —

2009 1/10/2009 9:00:00 AM 6/10/2009 10:00:00 AM 11/29/2009 9:00:00 AM

2010 1/10/2010 9:00:00 AM 6/10/2010 10:00:00 AM 11/29/2010 9:00:00 AM

2011 1/10/2011 9:00:00 AM 6/10/2011 10:00:00 AM 11/29/2011 10:00:00 AM

2012 1/10/2012 9:00:00 AM 6/10/2012 9:00:00 AM 11/29/2012 9:00:00 AM

2013 1/10/2013 9:00:00 AM 6/10/2013 9:00:00 AM 11/29/2013 9:00:00 AM

2014 1/10/2014 9:00:00 AM 6/10/2014 9:00:00 AM 11/29/2014 9:00:00 AM

2015 1/10/2015 9:00:00 AM 6/10/2015 9:00:00 AM 11/29/2015 9:00:00 AM

2016 1/10/2016 9:00:00 AM 6/10/2016 9:00:00 AM 11/29/2016 9:00:00 AM

Теперь посмотрим результат после установки обновления:

year a b c

—- — — —

2009 1/10/2009 8:00:00 AM 6/10/2009 9:00:00 AM 11/29/2009 8:00:00 AM

2010 1/10/2010 8:00:00 AM 6/10/2010 9:00:00 AM 11/29/2010 8:00:00 AM

2011 1/10/2011 8:00:00 AM 6/10/2011 9:00:00 AM 11/29/2011 9:00:00 AM

2012 1/10/2012 8:00:00 AM 6/10/2012 8:00:00 AM 11/29/2012 8:00:00 AM

2013 1/10/2013 8:00:00 AM 6/10/2013 8:00:00 AM 11/29/2013 8:00:00 AM

2014 1/10/2014 9:00:00 AM 6/10/2014 9:00:00 AM 11/29/2014 8:00:00 AM

2015 1/10/2015 8:00:00 AM 6/10/2015 8:00:00 AM 11/29/2015 8:00:00 AM

2016 1/10/2016 8:00:00 AM 6/10/2016 8:00:00 AM 11/29/2016 8:00:00 AM

Обратите внимание: после установки обновления в предыдущие годы время стало меньше на один час, как и положено: теперь у нас UTC+3, а не UTC+4. (Тут как раз кроется засада для программ, которые работают с событиями, привязанными к локальному времени). А вот для нынешнего 2014-го года смешение осталось прежним – UTC+4. Откуда взялся один час пока не ясно, поэтому продолжаем анализ.

Для начала опять посмотрим реестр.

До установки обновления:

После установки обновления:

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

Давайте расшифруем эти записи с помощью Powershell.

До установки обновления:

PS C:\Users\1> $a=[system.timezoneinfo]::FindSystemTimeZoneById(«Russian Standard Time»)

PS C:\Users\1> $a | fl *

Id : Russian Standard Time

DisplayName : (UTC+04:00) Moscow, St. Petersbur

StandardName : Russian Standard Time

DaylightName : Russian Daylight Time

BaseUtcOffset : 04:00:00

SupportsDaylightSavingTime : True

PS C:\Users\1> $a.GetAdjustmentRules()

DateStart : 1/1/0001 12:00:00 AM

DateEnd : 12/31/2010 12:00:00 AM

DaylightDelta : 01:00:00

DaylightTransitionStart : System.TimeZoneInfo+TransitionTime

DaylightTransitionEnd : System.TimeZoneInfo+TransitionTime

DateStart : 1/1/2011 12:00:00 AM

DateEnd : 12/31/2011 12:00:00 AM

DaylightDelta : 01:00:00

DaylightTransitionStart : System.TimeZoneInfo+TransitionTime

DaylightTransitionEnd : System.TimeZoneInfo+TransitionTime

Последние два значения не видно, поэтому

Полная расшифровка:

Monday, January 1, 0001 12:00:00 AM

Friday, December 31, 2010 12:00:00 AM

01:00:00

TimeOfDay : 1/1/0001 2:00:00 AM

Month : 3

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

TimeOfDay : 1/1/0001 3:00:00 AM

Month : 10

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

————————————

Saturday, January 1, 2011 12:00:00 AM

Saturday, December 31, 2011 12:00:00 AM

01:00:00

TimeOfDay : 1/1/0001 2:00:00 AM

Month : 3

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

TimeOfDay : 1/1/0001 12:00:00 AM

Month : 1

Week : 1

Day : 1

DayOfWeek : Saturday

IsFixedDateRule : False

После установки обновления:

$a=[system.timezoneinfo]::FindSystemTimeZoneById(«Russian Standard Time»)

$a | fl *

Id : Russian Standard Time

DisplayName : (UTC+03:00) Moscow, St. Petersburg, Volgograd (RTZ 2)

StandardName : Russia TZ 2 Standard Time

DaylightName : Russia TZ 2 Daylight Time

BaseUtcOffset : 03:00:00

SupportsDaylightSavingTime : True

PS C:\Users\1> $a.GetAdjustmentRules()

DateStart : 1/1/0001 12:00:00 AM

DateEnd : 12/31/2010 12:00:00 AM

DaylightDelta : 01:00:00

DaylightTransitionStart : System.TimeZoneInfo+TransitionTime

DaylightTransitionEnd : System.TimeZoneInfo+TransitionTime

DateStart : 1/1/2011 12:00:00 AM

DateEnd : 12/31/2011 12:00:00 AM

DaylightDelta : 01:00:00

DaylightTransitionStart : System.TimeZoneInfo+TransitionTime

DaylightTransitionEnd : System.TimeZoneInfo+TransitionTime

DateStart : 1/1/2014 12:00:00 AM

DateEnd : 12/31/2014 12:00:00 AM

DaylightDelta : 01:00:00

DaylightTransitionStart : System.TimeZoneInfo+TransitionTime

DaylightTransitionEnd : System.TimeZoneInfo+TransitionTime

Полная расшифровка:

Monday, January 1, 0001 12:00:00 AM

Friday, December 31, 2010 12:00:00 AM

01:00:00

TimeOfDay : 1/1/0001 2:00:00 AM

Month : 3

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

TimeOfDay : 1/1/0001 3:00:00 AM

Month : 10

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

————————————

Saturday, January 1, 2011 12:00:00 AM

Saturday, December 31, 2011 12:00:00 AM

01:00:00

TimeOfDay : 1/1/0001 2:00:00 AM

Month : 3

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

TimeOfDay : 1/1/0001 12:00:00 AM

Month : 1

Week : 1

Day : 1

DayOfWeek : Saturday

IsFixedDateRule : False

————————————

Wednesday, January 1, 2014 12:00:00 AM

Wednesday, December 31, 2014 12:00:00 AM

01:00:00

TimeOfDay : 1/1/0001 12:00:00 AM

Month : 1

Week : 1

Day : 1

DayOfWeek : Wednesday

IsFixedDateRule : False

TimeOfDay : 1/1/0001 2:00:00 AM

Month : 10

Week : 5

Day : 1

DayOfWeek : Sunday

IsFixedDateRule : False

Обратите внимание на последние две записи: первая означает включение летнего времени с начала 2014 года, а вторая переход на зимнее время в 2 часа в последнее воскресение октября – ныне это 26 октября.

Вот собственно и всё по технике перевода времени.

Если ещё раз посмотреть на исходные таблицы с контрольными точками времени (до установки обновления), то можно увидеть «скачок» времени на границе года (тут даты не на границе года, но суть отражают правильно):

2011 1/10/2011 9:00:00 AM 6/10/2011 10:00:00 AM 11/29/2011 10:00:00 AM

2012 1/10/2012 9:00:00 AM 6/10/2012 9:00:00 AM 11/29/2012 9:00:00 AM

Понятно, что реально в тот момент время не менялось. Откуда скачок? Это эффект изменения часовых поясов: тогда тоже не просто отменили переход на летнее время – изменился часовой пояс.

Сейчас мы наблюдаем похожий «скачок» времени при переходе с 2013 года на 2014 за счёт изменения часового пояса:

2013 1/10/2013 8:00:00 AM 6/10/2013 8:00:00 AM 11/29/2013 8:00:00 AM

2014 1/10/2014 9:00:00 AM 6/10/2014 9:00:00 AM 11/29/2014 8:00:00 AM

2015 1/10/2015 8:00:00 AM 6/10/2015 8:00:00 AM 11/29/2015 8:00:00 AM

2016 1/10/2016 8:00:00 AM 6/10/2016 8:00:00 AM 11/29/2016 8:00:00 AM

Останется ли в будущем этот «скачок» в таблице? По всей видимости да. Какие последствия? Некоторые программы эту ситуацию не смогут обработать правильно: либо выдадут неправильный результат, либо завершатся аварийно. Неприятность нынешней ситуации в том, что если в прошлый раз один час на границе года «пропадал», то сейчас «появился» один фиктивный локальный час. Понятно, что это просто математический фокус. Программа отработает правильно, если для каждой даты будет учитывать часовой пояс на каждый момент времени. Делают ли это программы? Думаю, что большинство этого не делает, и в большинстве случаев это не нужно, но там, где это критично… в общем передавайте привет депутатам!

На этом всё. Надеюсь, что ваш мозг выдержал путешествия во времени J

PS: кто поставит на то, что будет ещё одно обновление в следующем году, которое «отполирует» текущее обновление?

PSS: код расшифровки

$a=[system.timezoneinfo]::FindSystemTimeZoneById(«Russian Standard Time»)

$a.GetAdjustmentRules()

$b=$a.GetAdjustmentRules()

$b | % {

$_.DateStart

$_.DateEnd

$_.DaylightDelta.ToString()

$_.DaylightTransitionStart

$_.DaylightTransitionEnd

«————————————»

}

Вывод контрольных точек:

$UtcTime2009 = Get-Date -Date «2009-01-10 5:00:00Z»

$UtcTime2010 = Get-Date -Date «2010-01-10 5:00:00Z»

$UtcTime2011 = Get-Date -Date «2011-01-10 5:00:00Z»

$UtcTime2012 = Get-Date -Date «2012-01-10 5:00:00Z»

$UtcTime2013 = Get-Date -Date «2013-01-10 5:00:00Z»

$UtcTime2014 = Get-Date -Date «2014-01-10 5:00:00Z»

$UtcTime2015 = Get-Date -Date «2015-01-10 5:00:00Z»

$UtcTime2016 = Get-Date -Date «2016-01-10 5:00:00Z»

$UtcTime2009b = Get-Date -Date «2009-06-10 5:00:00Z»

$UtcTime2010b = Get-Date -Date «2010-06-10 5:00:00Z»

$UtcTime2011b = Get-Date -Date «2011-06-10 5:00:00Z»

$UtcTime2012b = Get-Date -Date «2012-06-10 5:00:00Z»

$UtcTime2013b = Get-Date -Date «2013-06-10 5:00:00Z»

$UtcTime2014b = Get-Date -Date «2014-06-10 5:00:00Z»

$UtcTime2015b = Get-Date -Date «2015-06-10 5:00:00Z»

$UtcTime2016b = Get-Date -Date «2016-06-10 5:00:00Z»

$UtcTime2009c = Get-Date -Date «2009-11-29 5:00:00Z»

$UtcTime2010c = Get-Date -Date «2010-11-29 5:00:00Z»

$UtcTime2011c = Get-Date -Date «2011-11-29 5:00:00Z»

$UtcTime2012c = Get-Date -Date «2012-11-29 5:00:00Z»

$UtcTime2013c = Get-Date -Date «2013-11-29 5:00:00Z»

$UtcTime2014c = Get-Date -Date «2014-11-29 5:00:00Z»

$UtcTime2015c = Get-Date -Date «2015-11-29 5:00:00Z»

$UtcTime2016c = Get-Date -Date «2016-11-29 5:00:00Z»

$out = @()

$out += [pscustomobject]@{«year»=»2009»;»a»=$UtcTime2009;»b»=$UtcTime2009b;»c»=$UtcTime2009c}

$out += [pscustomobject]@{«year»=»2010»;»a»=$UtcTime2010;»b»=$UtcTime2010b;»c»=$UtcTime2010c}

$out += [pscustomobject]@{«year»=»2011»;»a»=$UtcTime2011;»b»=$UtcTime2011b;»c»=$UtcTime2011c}

$out += [pscustomobject]@{«year»=»2012»;»a»=$UtcTime2012;»b»=$UtcTime2012b;»c»=$UtcTime2012c}

$out += [pscustomobject]@{«year»=»2013»;»a»=$UtcTime2013;»b»=$UtcTime2013b;»c»=$UtcTime2013c}

$out += [pscustomobject]@{«year»=»2014»;»a»=$UtcTime2014;»b»=$UtcTime2014b;»c»=$UtcTime2014c}

$out += [pscustomobject]@{«year»=»2015»;»a»=$UtcTime2015;»b»=$UtcTime2015b;»c»=$UtcTime2015c}

$out += [pscustomobject]@{«year»=»2016»;»a»=$UtcTime2016;»b»=$UtcTime2016b;»c»=$UtcTime2016c}

$out

Реклама

Один ответ

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s

%d такие блоггеры, как: