DateTimeの比較で、とんでもない欠陥のように見えることに気づきました。
DateTime d = DateTime.Now;
DateTime dUtc = d.ToUniversalTime();
d == dUtc; // false
d.Equals(dUtc); //false
DateTime.Compare(d, dUtc) == 0; // false
1つがDateTimeKind.Localで、もう1つがDateTimeKind.UTCの場合、DateTimeでのすべての比較操作は、どのタイプのスマート変換も実行できないようです。比較に含まれる両方を常にutc時間に変換する以外に、DateTimeを確実に比較するためのより良い方法はありますか?
編集、私の元の答えは部分的に間違っていました:
.Equal
または.Compare
を呼び出すと、内部で値.InternalTicks
が比較されます。このフィールドはunequalです。これは、世界時で時刻を表すために数時間調整されているためです。このように表示されるはずです。DateTimeオブジェクトは、名前のないタイムゾーンでtimeを表しますが、世界時とタイムゾーンではありません。タイムゾーンは、ローカル(システムのタイムゾーン)またはUTCです。これは、DateTimeクラスの欠如と考えるかもしれません。
convertingを別のタイムゾーンに変換する場合、時刻は調整され、調整されます。これがおそらく、マイクロソフトがUTCに変換するときにアクションが実行されることを強調するために、プロパティではなくメソッドを使用することを選択した理由です。
もともと私は構造体が比較され、System.DateTime.Kind
のフラグが異なることをここに書きました。これは真実ではありません。異なるのはティックの量です。
t1.Ticks == t2.Ticks; // false
t1.Ticks.Equals(t2.Ticks); // false
2つの日付を安全に比較するために、それらを同じ種類に変換できます。比較する前に日付を世界時に変換すると、後の結果が得られます。
DateTime t1 = DateTime.Now;
DateTime t2 = t1;
DateTime.Compare(t1.ToUniversalTime(), t2.ToUniversalTime()); // 0
DateTime.Equals(t1.ToUniversalTime(), t2.ToUniversalTime()); // true
道徳:決してDateTime
単純に比較しない
これに対処するために、DateTimeとTimeZoneを含む独自のDateTimeオブジェクト(SmartDateTimeと呼ぶことにします)を作成しました。 ==やCompareなどのすべての演算子をオーバーライドし、元のDateTime演算子を使用して比較を行う前にUTCに変換します。