3

次のような夏時間によって引き起こされる時間の変化を説明しようとする古いコードがいくつかあります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 31; i++)
            {
                DateTime dt = new DateTime(1960, 3, i, 0, 0, 0);
                Console.WriteLine(dt.ToUniversalTime());
            }

            Console.WriteLine();

            for (int i = 1; i <= 30; i++)
            {
                DateTime dt = new DateTime(1960, 4, i, 0, 0, 0);
                Console.WriteLine(dt.ToUniversalTime());
            }

            Console.ReadKey();
        }
    }
}

このコードは、1960年の3月と4月の日を繰り返し、日時を出力します。ただし、これは1960年の時間変更を正しく考慮していないため、時間変更の日付が当時とは異なっていたと思います。TimeZoneInfoクラスを使用してこれを修正しようとしました。コードを次のように変更しました。

class Program
    {
        static void Main(string[] args)
        {
            for (int i = 1; i <= 31; i++)
            {
                DateTime dt = new DateTime(1960, 3, i, 0, 0, 0);
                var tz = TimeZoneInfo.Local;
                var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
                //use timeZoneInfo class to account for dlst offset
                Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
            }

            Console.WriteLine();

            for (int i = 1; i <= 30; i++)
            {
                DateTime dt = new DateTime(1960, 4, i, 0, 0, 0);
                var tz = TimeZoneInfo.Local;
                var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
                //use timeZoneInfo class to account for dlst offset
                Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));

            }

            Console.ReadKey();
        }
    }

残念ながら、これは印刷中です: ここに画像の説明を入力してください

これは、夏時間が4月3日の午後4時に変更され、4月24日の午前2時に切り替えられる必要があることを示しています。夏時間を正しく説明するために何が欠けていますか?

編集: 私の現在のタイムゾーンは東です。

4

2 に答える 2

2

Windowsのタイムゾーン情報が、TZDBで期待していたものと一致していないようです。これは、 Noda Timeを使用して、BCL TimeZoneInfo(ラップ)とTZDB 2012iデータの両方を使用して、1960年から1965年までのすべての遷移を表示するプログラムです。

using System;
using NodaTime;

class Test
{
    static void Main()
    {
        var bcl = DateTimeZoneProviders.Bcl["Eastern Standard Time"];
        var tzdb = DateTimeZoneProviders.Tzdb["America/New_York"];

        ShowTransitions(bcl);
        ShowTransitions(tzdb);
    }

    static void ShowTransitions(DateTimeZone zone)
    {
        Console.WriteLine("Transitions for {0}", zone.Id);
        Instant start = Instant.FromUtc(1960, 1, 1, 0, 0);
        Instant end = Instant.FromUtc(1965, 1, 1, 0, 0);
        var interval = zone.GetZoneInterval(start);
        while (interval.Start < end)
        {
            Console.WriteLine(interval.Start);
            interval = zone.GetZoneInterval(interval.End);
        }
        Console.WriteLine();
    }
}

出力:

Transitions for Eastern Standard Time
1959-10-25T06:00:00Z
1960-04-03T07:00:00Z
1960-10-30T06:00:00Z
1961-04-02T07:00:00Z
1961-10-29T06:00:00Z
1962-04-01T07:00:00Z
1962-10-28T06:00:00Z
1963-04-07T07:00:00Z
1963-10-27T06:00:00Z
1964-04-05T07:00:00Z
1964-10-25T06:00:00Z

Transitions for America/Toronto
1959-10-25T06:00:00Z
1960-04-24T07:00:00Z
1960-10-30T06:00:00Z
1961-04-30T07:00:00Z
1961-10-29T06:00:00Z
1962-04-29T07:00:00Z
1962-10-28T06:00:00Z
1963-04-28T07:00:00Z
1963-10-27T06:00:00Z
1964-04-26T07:00:00Z
1964-10-25T06:00:00Z

「東部標準時」にマップされるタイムゾーンIDは他にもありますが、Windowsの動作に一致するものは見つかりませんでした。

これはバグではないと思いTimeZoneInfoます。基になるWindowsのタイムゾーンデータに潜在的な問題があると思います。

もちろん、TZDBデータを照合したい場合は、NodaTimeを使用できます:)

于 2012-11-08T17:25:56.430 に答える
1

dt.IsDaylightSavingTime()があります。そしてそれは1960年に私にとって(あなたより1日遅れて)4/4に変わりますが、私はCSTです。2012年の場合、私のシステムでは正しいです。バグの可能性があります。それはちょうどその年かXまでのすべての年かもしれません。

私はこれがそれを説明すると思います:

夏時間

「1960年代初頭、夏時間の遵守は非常に一貫性がなく、時間の遵守の寄せ集めがあり、時計をいつ変更するかについての合意はありませんでした。」

「1966年の統一時間法により、米国全体で(各タイムゾーン内で)夏時間が統一されるシステムが確立されました。」

于 2012-11-08T16:57:56.350 に答える