И снова об «Incorrect time zone information for Russian time zones » [.Net bug, ID: 693286]

в 10:37, , рубрики: .net

Добрый день, коллеги, спешу поделиться проблемой, возникшей при интеграции Java и .Net сервисов. Для пущей наглядности приведу пример: .Net сервис читает даные типа Date из базы данных, переводит их в тип long затем передает на сторону Java consumer'a, где уже из long создается полноценный инстанс java.util.Date. Всё бы ничего, до тех пор, пока мы не стали вычитывать исторические данные, то есть данные до знаменитой отмены перехода на зимнее-или-уж-какое-там-время. .Net сервис (в русской time-zone) передает дату (или более точно формирует long) для «01/01/2010 13:00:00», а на стороне Java создается инстанс java.util.Date как «01/01/2010 12:00:00». Откуда эта непонятная разница в час ?! Начиаем исследовать.

Итак, Java code:

public class Main {

    public static void main(String[] args) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        TimeZone tzMoscow = TimeZone.getTimeZone("Europe/Moscow");
        TimeZone tzLondon = TimeZone.getTimeZone("Europe/London");

        System.out.println("Before Medvedev tricks: " + calcTimeZoneShift(tzLondon, tzMoscow, "2010-01-01T13:00:00", format));
        System.out.println("After Medvedev tricks: " + calcTimeZoneShift(tzLondon, tzMoscow, "2013-01-01T13:00:00", format));
    }

    static private long calcTimeZoneShift(TimeZone tz1, TimeZone tz2, String time, SimpleDateFormat format)
            throws ParseException{

        format.setTimeZone(tz1);
        Date date1 = format.parse(time);

        format.setTimeZone(tz2);
        Date date2 = format.parse(time);
        return (date1.getTime() - date2.getTime())/3600000;

    };

}

Output:
Before Medvedev tricks: 3
After Medvedev tricks: 4

Вроде все верно: до Медведева разница зимой и летом с Лондоном была в 3 часа, а вот после Медведева разница зимой уже составила 4 часа.

Чем же нас удивит .Net:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            
            TimeZoneInfo tzMoscow = TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time");
            TimeZoneInfo tzLondon = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
            
            System.Diagnostics.Debug.WriteLine("Before Medvedev tricks: " + calcTimeZoneShift(tzLondon, tzMoscow, "01/01/2010 13:00:00"));
            System.Diagnostics.Debug.WriteLine("After Medvedev tricks: " + calcTimeZoneShift(tzLondon, tzMoscow, "01/01/2013 13:00:00"));

        }

        private static long calcTimeZoneShift(TimeZoneInfo tz1, TimeZoneInfo tz2, String time)
        {
            DateTime date = DateTime.Parse(time);
            DateTime newTime = TimeZoneInfo.ConvertTime(date, tz1, tz2);
            return (newTime.ToFileTimeUtc() - date.ToFileTimeUtc()) / 36000000000;
        }

    }
}

Output:
Before Medevedev tricks: 4
After Medevedev tricks: 4

Млииин, вот это да ?! То есть timezone shift оказывается одним и тем же как «до», так и «после». Продолжаем google-ить и находим:

Incorrect time zone information for Russian time zones by Бронников Павел

Type: Bug
ID: 693286
Opened: 10/5/2011 8:18:45 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration

Time zone information for Russian time zones is incorrect. I think this occurs after Russian government disable summer time. Issue occurs then I converting date in the past from UST time zone to one of Russian time zones using routine TimeZoneInfo.ConvertTimeFromUtc
Actual results
UTC 13.06.2010 00:00:00 = Moscow 13.06.2010 5:00:00
UTC 13.12.2010 00:00:00 = Moscow 13.12.2010 4:00:00

Expected results
UTC 13.06.2010 00:00:00 = Moscow 13.06.2010 4:00:00
UTC 13.12.2010 00:00:00 = Moscow 13.12.2010 3:00:00

Читаем ответ:

In short, the issue is not caused by a problem with the .NET framework. Instead, it is caused by an OS update that affected registry data describing some Russian time zones. The background is that Russia has changed its time zones, as well as their base offsets and DST rules all in the same year.

И как же так, у меня Windows 7, у меня все последние сервиспаки и самый последняя версия .Net и все равно ошибка, выявленная в 2011 году до сих пор не решена ?! Ладное пустое это все (я про вопли и про то, что в Java все работает «как надо»)… Просто учтитывайте этот баг при чтении не столь уж исторических данных.

Автор: slonnik3

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js