私には2つの日付プロパティがあり、それらは1つのオブジェクトから別のオブジェクトにマッピングしているのとまったく同じです。以下のように比較すると、falseが返されます。
if(obj1.d1 == obj2.d1)
{
}
どちらもです{01/06/2011 15:44:32}
。
DateTime.Compare
null許容型であるため使用できません。null許容の日付を比較するための最良の方法は何でしょうか?
私には2つの日付プロパティがあり、それらは1つのオブジェクトから別のオブジェクトにマッピングしているのとまったく同じです。以下のように比較すると、falseが返されます。
if(obj1.d1 == obj2.d1)
{
}
どちらもです{01/06/2011 15:44:32}
。
DateTime.Compare
null許容型であるため使用できません。null許容の日付を比較するための最良の方法は何でしょうか?
これらの日付の実際のティックを確認してください。異なる場合があります。DateTime
最小単位として 100 ns 間隔を記録することに注意してください。をフォーマットすると、これらは表示されませんDateTime
。
メソッドを使用して、null 許容日付を含む null 許容オブジェクトを比較できますNullable.Compare<T>()
。
if(Nullable.Compare(obj1.d1, obj2.d1) == 0)
{
}
それはうまくいくはずです、チェックしてください:
var now = DateTime.Now;
DateTime? d1 = now;
DateTime? d2 = now;
Console.WriteLine(d1 == d2); // Output: True
これらは実際にはまったく同じではないと思います。つまり、ミリ秒単位またはティック単位で異なります。
他の回答が示しているように、デフォルトの比較子は、null 許容の DateTime オブジェクトに対して正常に機能します。丸められた形式の日付を比較する方法をコメントで尋ねました。次のようなものが必要です。
if (dt1.EqualsRounded(dt2))
以下は、これを行うために必要なすべてのコードです。null 許容および null 非許容の DateTime を完全にサポートします。IComparer<T>
両方を実装してIEqualityComparer<T>
いるため、リストをソートするときにもこれを使用できます (たとえば)。上記のような単純なケースには拡張メソッドがあり、異なる丸め間隔を提供するオーバーロードがあります。指定しない場合、デフォルトで最も近い整数秒に丸められます。楽しみ!
public static class DateTimeExtensions
{
public static DateTime RoundToNearestInterval(this DateTime dateTime, TimeSpan interval)
{
// Adapted from http://stackoverflow.com/questions/1393696/c-rounding-datetime-objects
// do the rounding
var intervalTicks = interval.Ticks;
var ticks = (dateTime.Ticks + (intervalTicks / 2) + 1) / intervalTicks;
var totalTicks = ticks * intervalTicks;
// make sure the result is not to low
if (totalTicks < 0)
totalTicks = 0;
// make sure the result is not to high
const long maxTicks = 0x2bca2875f4373fffL; // DateTime.MaxTicks
if (totalTicks > maxTicks)
totalTicks = maxTicks;
// return the new date from the result
return new DateTime(totalTicks, dateTime.Kind);
}
public static bool EqualsRounded(this DateTime x, DateTime y)
{
return x.EqualsRounded(y, TimeSpan.FromSeconds(1));
}
public static bool EqualsRounded(this DateTime x, DateTime y, TimeSpan interval)
{
var comparer = new RoundedDateTimeComparer(interval);
return comparer.Equals(x, y);
}
public static bool EqualsRounded(this DateTime? x, DateTime? y)
{
return x.EqualsRounded(y, TimeSpan.FromSeconds(1));
}
public static bool EqualsRounded(this DateTime? x, DateTime? y, TimeSpan interval)
{
var comparer = new RoundedDateTimeComparer(interval);
return comparer.Equals(x, y);
}
public static int CompareRounded(this DateTime x, DateTime y)
{
return x.CompareRounded(y, TimeSpan.FromSeconds(1));
}
public static int CompareRounded(this DateTime x, DateTime y, TimeSpan interval)
{
var comparer = new RoundedDateTimeComparer(interval);
return comparer.Compare(x, y);
}
public static int CompareRounded(this DateTime? x, DateTime? y)
{
return x.CompareRounded(y, TimeSpan.FromSeconds(1));
}
public static int CompareRounded(this DateTime? x, DateTime? y, TimeSpan interval)
{
var comparer = new RoundedDateTimeComparer(interval);
return comparer.Compare(x, y);
}
}
public class RoundedDateTimeComparer :
IComparer<DateTime>, IComparer<DateTime?>,
IEqualityComparer<DateTime>, IEqualityComparer<DateTime?>
{
private readonly TimeSpan _interval;
public RoundedDateTimeComparer(TimeSpan interval)
{
_interval = interval;
}
public int Compare(DateTime x, DateTime y)
{
var roundedX = x.RoundToNearestInterval(_interval);
var roundedY = y.RoundToNearestInterval(_interval);
return roundedX.CompareTo(roundedY);
}
public int Compare(DateTime? x, DateTime? y)
{
return x.HasValue && y.HasValue ? Compare(x.Value, y.Value) : (y.HasValue ? 1 : (x.HasValue ? -1 : 0));
}
public bool Equals(DateTime x, DateTime y)
{
var roundedX = x.RoundToNearestInterval(_interval);
var roundedY = y.RoundToNearestInterval(_interval);
return roundedX.Equals(roundedY);
}
public bool Equals(DateTime? x, DateTime? y)
{
return x.HasValue && y.HasValue ? Equals(x.Value, y.Value) : x.Equals(y);
}
public int GetHashCode(DateTime obj)
{
var rounded = obj.RoundToNearestInterval(_interval);
return rounded.GetHashCode();
}
public int GetHashCode(DateTime? obj)
{
return obj.HasValue ? GetHashCode(obj.Value) : 0;
}
}
を使用する前に null かどうかを確認できません.Compare
か?