none
Ошибки часовых поясов после установки windows апдейта 2570791 RRS feed

  • Вопрос

  • После установки windows-апдейта http://support.microsoft.com/kb/2570791 для дат ранее марта 2011 года в .Net Framework 4.0 стало неправильно работать преобразование времени в UTC и обратно для всех российский таймзон. Теперь каждым летом до 2011 года часовой пояс Москвы, например, стал +5, а каждой зимой +4. Что неправильно.

    Я разрабатываю систему мониторинга авиасообщений РФ, и для архива данных по воздушному движению очень важно правильное преобразование времени и дат из UTC в местное время и обратно. Как сделать так, что бы Microsoft исправил эту ошибку? Понятно, что можно самим вручную настроить все правила перехода на летнее время для всех нужных таймзон, но очень не хочется этого делать, тем более это не гарантирует, что Microsoft снова не "улучшит" таймзоны очередным апдейтом, которые у нас ставятся автоматически.

    29 августа 2011 г. 11:06

Ответы

Все ответы

  • Тоже наткнулся. Завел баг https://connect.microsoft.com/VisualStudio/feedback/details/686169/incorrent-utc-to-local-time-conversion-after-kb-2570791. Нажмите там I can reproduce it.


    Paul
    • Помечено в качестве ответа Abolmasov Dmitry 1 сентября 2011 г. 8:06
    30 августа 2011 г. 12:31
  • Спасибо. Я баг еще вчера завл, но у вашего голосов куда больше :)

    Вот мой: https://connect.microsoft.com/VisualStudio/feedback/details/685959/new-russian-time-zones-failed-to-convert-time-correctly-for-previous-years

    30 августа 2011 г. 14:48
  • Я вчера долго пытался придумать как обойти этот баг, но решения так и не нашел.

    TimeZoneInfo не позволяет создать правило перехода на летнее время "всегда". Нужно обязательно задавать интервал. Поэтому хоть час, да вылетит.

    Вот максимум до чего я дошел:

    TimeZoneInfo oldTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time");

    TimeZoneInfo newTimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone(
        info.Id,
        TimeSpan.FromHours(3),
        info.DisplayName,
        info.StandardName,
        info.DaylightName,
        new TimeZoneInfo.AdjustmentRule[]
        {
                TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
                DateTime.MinValue.Date,
                new DateTime(2011, 4, 1),
                TimeSpan.FromHours(1),
                TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1,1,1,2,0,0), 3, 5, DayOfWeek.Sunday),
                TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1,1,1,3,0,0), 10, 5, DayOfWeek.Sunday)
            ),
            TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(
                new DateTime(2011, 4, 2),
                DateTime.MaxValue.Date,
                TimeSpan.FromHours(1),
                TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1,1,1,3,0,0,592), 2, 30),
                TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1,1,1,3,0,0,593), 2, 30)
            ),
        },
        false);

    Это работает для всех дат и времен кроме последнего дня февраля с 3:00 до 4:00 начиная с 2012-о года.

    Причем даже указание времени перехода в несуществующем времени 30-го февраля не решает проблему. Внутри кода TimeZoneInfo время действия правила округляется до последнего дня в месяце, так что вместо 30-го февраля переход происходит либо 29-го, либо 28-го. Я смотрел Reflector'ом.

    Единственное что можно еще попробовать, это задать BaseUtcOffset в 4 (для Москвы) одно обратное правило до апреля 2011 года, которое уменьшало бы время на час назад зимой. Но тогда летнее время будет считаться зимним а зимнее летним, что не айс. К тому же я не пробовал, и кто знает как TimeZoneInfo поведет себя при отрицательном смешении летнего времени.

    Так что похоже для России в Windows создать исторически корректные таймзоны сейчас нельзя. Только использовать комбинацию из 2-х таймзон.

    30 августа 2011 г. 15:02