Boa tarde, colegas, apresso-me a compartilhar o problema que surgiu durante a integração dos serviços Java e .Net. Por uma questão de clareza, darei um exemplo: o serviço .Net lê dados do tipo Data do banco de dados, converte-os para longos, depois transfere-os para o lado do consumidor Java, onde é criada uma instância completa de java.util.Date. Tudo ficaria bem até que começássemos a ler os dados históricos, isto é, os dados anteriores ao famoso cancelamento da transição para o inverno ou já lá. O serviço .Net (no fuso horário russo) transmite a data (ou forma mais precisa de um longo) para "01/01/2010 13:00:00" e, no lado Java, uma instância java.util.Date é criada como "01/01 / 2010 12:00:00. " De onde vem essa diferença incompreensível em uma hora ?! Começamos a explorar.Então, código 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
Parece que tudo é verdade: antes de Medvedev, a diferença no inverno e no verão com Londres era às 3 horas, mas depois de Medvedev a diferença no inverno já era de 4 horas.O que nos surpreenderá .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, uau ?! Ou seja, o deslocamento do fuso horário é o mesmo que "antes" e "depois". Continue pesquisando no Google e localize :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
Lemos a resposta:Em suma, o problema não é causado por um problema com a estrutura .NET. Em vez disso, é causada por uma atualização do sistema operacional que afeta os dados do registro que descrevem alguns fusos horários russos. O pano de fundo é que a Rússia mudou seus fusos horários, bem como suas compensações básicas e regras de horário de verão no mesmo ano.
E como é que eu tenho o Windows 7, tenho todos os service packs mais recentes e a versão mais recente do .Net, e ainda assim o erro detectado em 2011 ainda não foi resolvido ?! Ok, é tudo (estou falando de uivos e de que tudo funciona "como deveria" em Java) ... Leve esse bug em consideração ao ler dados não tão históricos.