Et encore une fois sur «Informations de fuseau horaire incorrectes pour les fuseaux horaires russes» [bogue .Net, ID: 693286]

Bonjour, chers collègues, je m'empresse de partager le problème qui s'est posé lors de l'intégration des services Java et .Net. Par souci de clarté, je vais donner un exemple: le service .Net lit les données de type Date dans la base de données, les traduit en long, puis les transmet au côté consommateur Java, où une instance java.util.Date complète est déjà créée à partir de long. Tout irait bien jusqu'à ce que nous commencions à lire les données historiques, c'est-à-dire les données avant la fameuse annulation de la transition vers l'heure d'hiver ou déjà là-bas. Le service .Net (dans le fuseau horaire russe) transmet la date (ou forme plus précisément un long) pour "01/01/2010 13:00:00", et côté Java, une instance java.util.Date est créée en tant que "01/01 / 2010 12:00:00. " D'où vient cette incompréhensible différence en une heure?! Nous commençons à explorer.

Donc, le code Java:
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


Il semble que tout soit vrai: avant Medvedev, la différence en hiver et en été avec Londres était à 3 heures, mais après Medvedev, la différence en hiver était déjà de 4 heures.

Ce qui va nous surprendre .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


Mliiin, wow?! Autrement dit, le décalage de fuseau horaire se révèle être le même que «avant» et «après». Continuez à le rechercher sur Google et trouvez :

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


Nous lisons la réponse:

En bref, le problème n'est pas causé par un problème avec le framework .NET. Au lieu de cela, il est causé par une mise à jour du système d'exploitation qui a affecté les données de registre décrivant certains fuseaux horaires russes. Le contexte est que la Russie a changé ses fuseaux horaires, ainsi que leurs décalages de base et les règles de l'heure d'été, au cours de la même année.


Et comment se fait-il que j'ai Windows 7, que j'ai tous les derniers service packs et la dernière version de .Net, et que l'erreur détectée en 2011 ne soit toujours pas résolue?! D'accord, c'est tout (je parle des hurlements et que tout fonctionne "comme il se doit" en Java) ... Tenez simplement compte de ce bogue lorsque vous lisez des données moins historiques.

All Articles