DateTimeOffsetを使用して、任意のタイムゾーンで特定の瞬間を伝えようとしています。 TimeZoneInfoを使用して夏時間を処理する方法がわかりません。
var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.BaseUtcOffset));
これは印刷されます:
6/2/2010 4:37:19 PM
6/2/2010 3:37:19 PM -06:00
私は中央のタイムゾーンにいます。現在、夏時間になっています。私は2行目を読み込もうとしています:
6/2/2010 4:37:19 PM -05:00
BaseUtcOffsetは明らかにDSTに基づいて変化しません。
適切なオフセット値で適切な時間を取得するにはどうすればよいですか?
TimeZoneInfoからUtcOffsetを取得し、それをToOffset()メソッドに渡す必要があります。
var dt = DateTime.UtcNow;
Console.WriteLine(dt.ToLocalTime());
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
TimeZoneInfo.ConvertTimeFromUtcを使用して、夏時間を許可することもできます。
DateTime utc = DateTime.UtcNow;
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utc, zone);
あるいは、タイムゾーン識別子をハードコーディングしたくない場合:
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id);
DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi);
私は.NETとstackoverflowの両方の初心者なので、間違っているかもしれませんが、ここに行きます:
TimeZoneInfo.ConvertTimeFromUtcを使用すると、サマータイムが可能になり、タイムゾーン+可能なDSTオフセットに従って正しい時間に変換されます。ただし、結果のオブジェクトのオフセット自体には標準時間のオフセットが表示され、夏時間は考慮されません。そのため、オブジェクトでToStringを実行する場合、正しい時間(時間と分)になりますが、サマータイム中のオフセットが間違っているため、後のコードで間違った瞬間につながる可能性があります。
代わりにGetUtcOffsetを使用して特定の時間のオフセットを取得し、DateTimeOffsetオブジェクトでToOffsetを実行すると、時間/分とオフセット自体の両方が正しく変換され、ToStringを安全に実行できます。
string ExpectedDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss''zzz";
string timeZoneId = "FLE Standard Time";
string dateTimestr = "2017-10-09T09:00:00+02:00";
DateTimeOffset dto = DateTimeOffset.Parse(dateTimeStr);
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
TimeSpan offset = zone.GetUtcOffset(dto);
dto = dto.ToOffset(offset);
string localTime = dto.ToString(ExpectedDateTimePattern);
localTimeは「2017-10-09T10:00:00 + 03:00」を返します。