Переход на летнее время до 1996 года - неожиданный результат - PullRequest
0 голосов
/ 28 апреля 2020

Я живу в Бельгии, и согласно этому сайту (https://www.astro.oma.be/GENERAL/INFO/fri001a.html) переход на летнее время меняется 30 сентября 1990 года в 1:00 UT C. В этот момент мы должны добавить только 1 час к UT C времени, чтобы получить местное время. За несколько дней до этого нам пришлось добавить 2 часа.

C# код (https://dotnetfiddle.net/5tSNyG)

using System;

public class Example
{
    public static void Main()
    {
        DateTime myUTCDate1, myUTCDate2, myUTCDate3, myUTCDate4;
        TimeZoneInfo tzLocal = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
        TimeZoneInfo tzUTC = TimeZoneInfo.FindSystemTimeZoneById("UTC");

        try {
            myUTCDate1 = new DateTime(1990, 09, 30, 0, 0, 0, DateTimeKind.Utc);
            myUTCDate2 = new DateTime(1990, 09, 30, 1, 0, 0, DateTimeKind.Utc);
            myUTCDate3 = new DateTime(1990, 10, 28, 0, 0, 0, DateTimeKind.Utc);
            myUTCDate4 = new DateTime(1990, 10, 28, 1, 0, 0, DateTimeKind.Utc);
            Console.WriteLine("tzLocal.Id: {0}\ntzLocal.DisplayName: {1}\n", tzLocal.Id, tzLocal.DisplayName);
            Console.WriteLine("{0} ({1}) -> {2} ({3})", myUTCDate1, tzUTC.Id, TimeZoneInfo.ConvertTime(myUTCDate1, tzUTC, tzLocal), tzLocal.Id);
            Console.WriteLine("{0} ({1}) -> {2} ({3})", myUTCDate2, tzUTC.Id, TimeZoneInfo.ConvertTime(myUTCDate2, tzUTC, tzLocal), tzLocal.Id);
            Console.WriteLine("{0} ({1}) -> {2} ({3})", myUTCDate3, tzUTC.Id, TimeZoneInfo.ConvertTime(myUTCDate3, tzUTC, tzLocal), tzLocal.Id);
            Console.WriteLine("{0} ({1}) -> {2} ({3})", myUTCDate4, tzUTC.Id, TimeZoneInfo.ConvertTime(myUTCDate4, tzUTC, tzLocal), tzLocal.Id);
        }
        catch (FormatException) {
            Console.WriteLine("Invalid format.");
            return;
        }
    }
}

C# вывод

tzLocal.Id: Стандартное романское время tzLocal.DisplayName: (UTC + 01: 00) Брюссель, Копенгаген, Мадрид, Париж 30.09.1990 12:00:00 (UT C) -> 30.09.1990 2:00:00 (стандартное романтическое время) // Добавлено 2 часа: ОК 30.09.1990 1:00:00 (UT C) -> 30.09.1990 3:00:00 (стандартное романтическое время) // Добавлено 2 часа: NOK (должно быть 1 добавленный час) 28.10.1990 12:00:00 (UT C) -> 28.10.1990 2:00:00 (стандартное романтическое время) // Добавлено 2 часа: NOK (должно быть 1 добавленный час) 28.10.1990 1:00:00 (UT C) -> 28.10.1990 2:00:00 (стандартное романтическое время) // 1 час добавлено: OK

Я не понимаю, почему переход на летнее время меняется только 28.10.1990 в 1:00:00 UT C. Я выполнил одно и то же упражнение в Oracle и Java, и результаты соответствуют ожидаемым (переход на летнее время меняется 30.09.1990 в 1:00:00 UT C). Я не эксперт. net и не могу объяснить разницу между net и Java / Oracle. Я что-то пропустил?

Но на этом другом веб-сайте (http://www.cedra.net/ENS/heuredete.html) я могу прочесть:

1996: ВНИМАНИЕ, изменение по взаимному согласию aux années précédentes. «Возвращение к жизни», октябрь, сентябрь, 2010г. в конце октября, а не в конце сентября, как в предыдущие годы. Возможно ли, что net не заботится об этом правиле?

Oracle query

SELECT 
SYS_EXTRACT_UTC(CAST(TO_TIMESTAMP('1990-09-30T01:00:00.0', 'YYYY-MM-DD"T"HH24:MI:SS.FF') AS TIMESTAMP WITH TIME ZONE)) AS D1,
SYS_EXTRACT_UTC(CAST(TO_TIMESTAMP('1990-09-30T02:00:00.0', 'YYYY-MM-DD"T"HH24:MI:SS.FF') AS TIMESTAMP WITH TIME ZONE)) AS D2
FROM DUAL;

Oracle output

D1: 1990-09-29 23:00:00 // 2 часа вычитается: ОК D2: 1990-09-30 01:00:00 // 1 час вычитается: ОК

Java код

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class test {
    public static void main(String[] args) {        
        DateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        dateFormatLocal.setTimeZone(TimeZone.getTimeZone("Europe/Brussels"));
        DateFormat dateFormatUTC = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        dateFormatUTC.setTimeZone(TimeZone.getTimeZone("UTC"));
        String[] dateStrArray = {"1990-09-30T01:00:00.000", "1990-09-30T02:00:00.000"};
        Date date = null;

        for (String dateStr : dateStrArray) { 
            try {
                date = dateFormatLocal.parse(dateStr);
                System.out.println(date + " (local) -> " + dateFormatUTC.format(date) + " (UTC)");
             } catch (ParseException e) {
                e.printStackTrace();
            }
       }
    }
}

Java выход

вс 30 сентября 01:00:00 CEST 1990 (местный) -> 1990-09-29T23: 00: 00.000 (UT C) // 2 часа вычитается: ОК Вс 30 сентября 02:00:00 CET 1990 (местный) -> 1990-09-30T01: 00: 00.000 (UT C) // 1 час вычитается: ОК

...