答えはあなたを驚かせるかもしれませんが、それはNOです。タイムゾーンが結果に影響しない限り、日、週、月、または年を追加することはできません。
その理由は、すべての現地日が 24 時間制であるとは限らないためです。タイムゾーン、そのゾーンの規則、および DST が問題の期間に移行しているかどうかによって、一部の「日」は 23、23.5、24、24.5、または 25 時間になる場合があります。(正確に言いたい場合は、代わりに「標準日」という用語を使用して、正確に 24 時間を意味することを示してください。)
例として、最初に、太平洋時間や東部時間など、DST のために変更される米国のタイム ゾーンの 1 つにコンピューターを設定します。次に、これらの例を実行します。
これは、2013年の「春先」への移行をカバーしています。
DateTime local1 = new DateTime(2013, 3, 10, 0, 0, 0, DateTimeKind.Local);
DateTime local2 = local1.AddDays(1);
DateTime utc1 = local1.ToUniversalTime();
DateTime utc2 = utc1.AddDays(1);
DateTime local3 = utc2.ToLocalTime();
Debug.WriteLine(local2); // 3/11/2013 12:00:00 AM
Debug.WriteLine(local3); // 3/11/2013 1:00:00 AM
そして、これは2013年の「フォールバック」移行をカバーしています:
DateTime local1 = new DateTime(2013, 11, 3, 0, 0, 0, DateTimeKind.Local);
DateTime local2 = local1.AddDays(1);
DateTime utc1 = local1.ToUniversalTime();
DateTime utc2 = utc1.AddDays(1);
DateTime local3 = utc2.ToLocalTime();
Debug.WriteLine(local2); // 11/4/2013 12:00:00 AM
Debug.WriteLine(local3); // 11/3/2013 11:00:00 PM
両方の例でわかるように、結果はどちらか一方に 1 時間ずれていました。
その他のポイント:
- 方法はありません
AddWeeks
。7 を掛けて、代わりに日数を追加します。
- 方法はありません
ToUtcTime
。を探していたと思いますToUniversalTime
。
- 電話しないでください
DateTime.Now.ToUniversalTime()
。内部.Now
ではUTC時間を取得し、とにかく現地時間に変換する必要があるため、これは冗長です。代わりに、を使用してDateTime.UtcNow
ください。
- このコードがサーバー上で実行されている場合は、種類のあるものを呼び出し
.Now
たり.ToLocalTime
、操作したりしないでください。そうする場合、ユーザーではなくサーバーのタイムゾーンを導入しています。ユーザーが同じタイム ゾーンにいない場合、またはアプリケーションを別の場所に展開した場合、問題が発生します。DateTime
Local
- この種の問題を回避したい場合は、NodaTimeを調べてください。API は、一般的な間違いを防ぐことができます。
代わりに、次のことを行う必要があります。
// on the client
DateTime local = new DateTime(2013, 3, 10, 0, 0, 0, DateTimeKind.Local);
DateTime utc = local.ToUniversalTime();
string zoneId = TimeZoneInfo.Local.Id;
// send both utc time and zone to the server
// ...
// on the server
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
DateTime theirTime = TimeZoneInfo.ConvertTimeFromUtc(utc, tzi);
DateTime newDate = theirTime.AddDays(1);
Debug.WriteLine(newDate); // 3/11/2013 12:00:00 AM
参考までに、代わりに Noda Time を使用した場合は次のようになります。
// on the client
LocalDateTime local = new LocalDateTime(2013, 3, 10, 0, 0, 0);
DateTimeZone zone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
ZonedDateTime zdt = local.InZoneStrictly(zone);
// send zdt to server
// ...
// on the server
LocalDateTime newDate = zdt.LocalDateTime.PlusDays(1);
Debug.WriteLine(newDate); // 3/11/2013 12:00:00 AM