日付のMath.Min&Math.Maxと同等ですか?


369

2つの日付の間の最小値(または最大値)を取得する最も速くて簡単な方法は何ですか?日付のMath.Min(&Math.Max)に相当するものはありますか?

私は次のようなことをしたいです:

 if (Math.Min(Date1, Date2) < MINIMUM_ALLOWED_DATE) {
      //not allowed to do this
 }

明らかに、上記のMath.Minは日付であるため機能しません。

回答:


416

DateTime値のオーバーロードはありませんがTicks、値に含まれる長い値を取得し、それらを比較して、結果から新しいDateTime値を作成できます。

new DateTime(Math.Min(Date1.Ticks, Date2.Ticks))

(DateTime構造体にKindは、新しい値で保持されないプロパティも含まれていることに注意してください。通常、これは問題ではありません。異なる種類のDateTime値を比較する場合、比較は意味がありません。)


2
このMath.Minの等価1つのライン置換/に最も近いように私には見えたが、他の回答を完全にするために、あまりにも素晴らしかった
— hawbsl

6
- 、あなたは完全にオリジナルの(ダニを除く)すべての情報失うSystem.DateTime-instance
— アンドレアスNiedermair

9
@AndreasNiedermair:異なる種類の日付を比較する場合、とにかくそれらを直接比較することはできません。私は答えですでにこれをカバーしました。
— グッファ

4
@Iain:いつでもそれらを比較できますが、比較できない値を比較すると、結果は役に立ちません。これは、キロメートル単位の距離とマイル単位の距離を比較するなど、比較できない他の値とまったく同じです。値をうまく比較できますが、それは何も意味しません。
— Guffa

4
種類について手を振る場合は-1。@ user450の回答に示されているように、両方の時間をUTCに変換し、情報を破棄せずに安全に比較することは非常に簡単です。
— ピエダー2017

484

それを行うための組み込みメソッドはありません。次の式を使用できます。

(date1 > date2 ? date1 : date2)

2つの最大値を見つけます。

計算MinするMaxため、または任意のタイプ(Comparer<T>.Default適切に設定されている場合)のジェネリックメソッドを記述できます。

public static T Max<T>(T first, T second) {
    if (Comparer<T>.Default.Compare(first, second) > 0)
        return first;
    return second;
}

LINQも使用できます。

new[]{date1, date2, date3}.Max()

15
これは実際に受け入れられるべき答えです。
— ラリー

38

どうですか:

public static T Min<T>(params T[] values)
{
    if (values == null) throw new ArgumentNullException("values");
    var comparer = Comparer<T>.Default;
    switch(values.Length) {
        case 0: throw new ArgumentException();
        case 1: return values[0];
        case 2: return comparer.Compare(values[0],values[1]) < 0
               ? values[0] : values[1];
        default:
            T best = values[0];
            for (int i = 1; i < values.Length; i++)
            {
                if (comparer.Compare(values[i], best) < 0)
                {
                    best = values[i];
                }
            }
            return best;
    }        
}
// overload for the common "2" case...
public static T Min<T>(T x, T y)
{
    return Comparer<T>.Default.Compare(x, y) < 0 ? x : y;
}

IComparable<T>またはをサポートするすべてのタイプで機能しますIComparable。

実際、LINQを使用する場合、別の方法は次のとおりです。

var min = new[] {x,y,z}.Min();

6
LINQの例に投票してください。
— ラウンドレス2013年

20
public static class DateTool
{
    public static DateTime Min(DateTime x, DateTime y)
    {
        return (x.ToUniversalTime() < y.ToUniversalTime()) ? x : y;
    }
    public static DateTime Max(DateTime x, DateTime y)
    {
        return (x.ToUniversalTime() > y.ToUniversalTime()) ? x : y;
    }
}

これにより、日付に異なる「種類」を持たせることができ、渡されたインスタンスが返されます(ティックまたはミリ秒から構築された新しいDateTimeは返されません)。

[TestMethod()]
    public void MinTest2()
    {
        DateTime x = new DateTime(2001, 1, 1, 1, 1, 2, DateTimeKind.Utc);
        DateTime y = new DateTime(2001, 1, 1, 1, 1, 1, DateTimeKind.Local);

        //Presumes Local TimeZone adjustment to UTC > 0
        DateTime actual = DateTool.Min(x, y);
        Assert.AreEqual(x, actual);
    }

このテストはグリニッジの東で失敗することに注意してください...


ToUniversalTime()パーツを単にドロップしないのはなぜですか?
— David Thielen

18

Linq.Min()/ Linq.Max()アプローチ:

DateTime date1 = new DateTime(2000,1,1);
DateTime date2 = new DateTime(2001,1,1);

DateTime minresult = new[] { date1,date2 }.Min();
DateTime maxresult = new[] { date1,date2 }.Max(); 

17

Math.Maxのようにそれを呼び出したい場合は、次のような非常に短い式の本体のようなことができます。

public static DateTime Max(params DateTime[] dates) => dates.Max();
[...]
var lastUpdatedTime = DateMath.Max(feedItemDateTime, assemblyUpdatedDateTime);

ああ、それは天才です!このようにして、毎回比較する必要はありません。データを処理した後の1回だけです。どうもありがとうございました!
— tfrascaroli

これは非常にエレガントなソリューションです
— pberggreen

2

どの程度DateTime拡張メソッド?

public static DateTime MaxOf(this DateTime instance, DateTime dateTime)
{
    return instance > dateTime ? instance : dateTime;
}

使用法:

var maxDate = date1.MaxOf(date2);

として使用したいのDateTime.MaxOf(dt1, dt2)ですが、その方法がわかりません...
— Zach Smith

@ZachSmith DateTimeクラスは部分的ではないため、オーバーロードできません。たぶん、DateTimeHelper.Max(dt1、
— dt2

@ shtse8-オーバーロードとはどういう意味ですか?拡張メソッドを追加することを考えていました。それ以来、インスタンス化されたインスタンスなしでは実行できないことを学びました。拡張メソッドを追加することはオーバーロードの一形態であると言っているように聞こえますか?私はそれを検討したことがありません。今私はそれについて考えています...オーバーロードは正確にはどういう意味ですか?
— ザック・スミス

@ZachSmithおお、DateTime静的メンバーに基づく「DateTime.Now」と同じように、「DateTime.MaxOf(dt1、dt2)」という拡張機能を追加していると思いました。
— shtse8 2018

-2

これでLINQができたので、2つの値(DateTimes、TimeSpansなど)で配列を作成し、.Max()拡​​張メソッドを使用できます。

var values = new[] { Date1, Date2 }; 
var max = values.Max(); 

読みやすく、Maxと同じくらい効率的で、2つ以上の比較値で再利用できます。

以下の.Kindについて心配することの全体的な問題は大したことです...しかし、私はこれまでに現地時間で作業しないことでそれを回避しています。時間に関して何か重要なことがあれば、そこにたどり着くためにさらに多くの仕事が必要であっても、私は常にUTCで働いています。


1
私の回答のコピー
— Toshi

-3
// Two different dates
var date1 = new Date(2013, 05, 13); 
var date2 = new Date(2013, 04, 10) ;
// convert both dates in milliseconds and use Math.min function
var minDate = Math.min(date1.valueOf(), date2.valueOf());
// convert minDate to Date
var date = new Date(minDate); 

http://jsfiddle.net/5CR37/


(本当に)良い提案ですが、説明がないと、なぜそれが良いのかを見つけるのは困難です。トリックがどこにあるか説明してください。説明がなければ、それは単なるコードのブロックであり、答えではありません。
— Artemix 2013年

3
質問には、JavaScriptではなく.NETのタグが付けられています
— hawbsl

申し訳ありませんが、.NETに気づきませんでした。とにかく、クライアント側で最小日付を見つけてサーバーに送信できます。
— Sergey Suvorov 2013年

4
あなたは私たちがaspについて話していると仮定しますが、これは必ずしも正しくありません。リスクがはるかに高いため(JavaScriptが無効)、不要なトラフィックが生成され、(ネットワーク速度に応じて)遅くなるため、クライアントでの違いを計算するのはかなり愚かです
— jalgames
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.