あなたが持っているのは現地時間であり、その時間があいまいである場合、はを正確なUTCインスタントに変換できません。そういうわけで、私たちは "あいまい"と言います。
たとえば、IANAゾーン名がAmerica/Chicago
で、WindowsゾーンIDがCentral Standard Time
である米国中部標準時ゾーンでは、「中央標準時」と「中央夏時間」の両方をカバーしています。私が知っていることは、2013年11月3日午前1時に、この時間があいまいであり、これが中央夏時間にあった午前1時の最初のインスタンスかどうかを知る方法は全くありません(UTC-5)、または中央標準時(UTC-6)のいずれかです。
曖昧な時刻をUTCに変換するかどうかを尋ねられたときに、プラットフォームによって異なる処理が行われます。いくつかは、通常は夏時間である最初のインスタンスになります。標準時間は通常は2番目のインスタンスになります。例外を投げるものもあれば、NodaTimeのようなものもあります。
最初にTimeZoneInfo
から始めましょう。
// Despite the name, this zone covers both CST and CDT.
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var dt = new DateTime(2013, 11, 3, 1, 0, 0);
var utc = TimeZoneInfo.ConvertTimeToUtc(dt, tz);
Debug.WriteLine(utc); // 11/3/2013 7:00:00 AM
ご覧のとおり、.netは「標準」時間(UTC-6)を使用することを選択しました。 (1AMに6時間を追加すると7AMになります)。時間があいまいだったという警告は皆さんにはありませんでした。あなたはこのように、自分自身をチェックしている可能性:
if (tz.IsAmbiguousTime(dt))
{
throw new Exception("Ambiguous Time!");
}
をしかし、これを強制するものではありません。あなたはそれを自分で確認する必要があります。
曖昧さを持たない唯一の方法はではなく、のタイプはDateTime
です。代わりに、DateTimeOffset
を使用できます。お守り:今
// Central Standard Time
var dto = new DateTimeOffset(2013, 11, 3, 1, 0, 0, TimeSpan.FromHours(-6));
var utc = dto.ToUniversalTime();
Debug.WriteLine(utc); // 11/3/2013 7:00:00 AM +00:00
// Central Daylight Time
var dto = new DateTimeOffset(2013, 11, 3, 1, 0, 0, TimeSpan.FromHours(-5));
var utc = dto.ToUniversalTime();
Debug.WriteLine(utc); // 11/3/2013 6:00:00 AM +00:00
、NodaTimeにこれを比較します
var tz = DateTimeZoneProviders.Tzdb["America/Chicago"];
var ldt = new LocalDateTime(2013, 11, 3, 1, 0, 0);
// will throw an exception, only because the value is ambiguous.
var zdt = tz.AtStrictly(ldt);
// will pick the standard time, like TimeZoneInfo did
var zdt = tz.AtLeniently(ldt);
// manually specify the offset for CST
var zdt = new ZonedDateTime(ldt, tz, Offset.FromHours(-6));
// manually specify the offset for CDT
var zdt = new ZonedDateTime(ldt, tz, Offset.FromHours(-5));
// with any of the above, once you have a ZonedDateTime
// you can get an instant which represents UTC
var instant = zdt.ToInstant();
をあなたが見ることができるように、多くのオプションがあります。すべては有効で、あなたがしたいことだけに依存します。
あいまいさを完全に避けたい場合は、常にDateTimeOffset
のままにするか、NodaTimeを使用する場合はZonedDateTime
またはOffsetDateTime
を使用してください。 DateTime
またはLocalDateTime
を使用する場合は、あいまいさが避けられません。
Noda Timeは、このようなシナリオに役立つように特別に設計されています。 – SLaks