是否等效于日期的Math.Min和Math.Max?


369

在两个日期之间获取最小值(或最大值)的最快,最简单的方法是什么?日期是否等于Math.Min(&Math.Max)?

我想做类似的事情:

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

显然,上述Math.Min无法使用,因为它们是日期。

Answers:


416

DateTime值没有重载,但是您可以获取Ticks值包含的long值,将它们进行比较,然后从结果中创建一个新的DateTime值:

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

(请注意,DateTime结构还包含一个Kind属性,该属性不会保留在新值中。这通常不成问题;如果您比较不同类型的DateTime值,则该比较毫无意义。)


2
在我看来,这最接近Math.Min的一行替换/等效记录,但是对于完整性而言,其他答案也很棒
hawbsl 2010年

6
-,您完全失去了原始System.DateTime实例的所有信息(剔号除外)
Andreas Niedermair 2012年

9
@AndreasNiedermair:如果您要比较不同类型的日期,则不能直接比较它们。我已经在答案中提到了这一点。
古法(Guffa)2012年

4
@Iain:您始终可以比较它们,但是如果比较不具有可比性的值,则结果将无用。它与其他任何不可比较的值相同,例如将以公里为单位的距离与以英里为单位的距离进行比较;您可以很好地比较这些值,但这没有任何意义。
Guffa 2013年

4
-1用于手挥动的种类。如@ user450的答案所示,将两个时间都转换为UTC并在不丢弃信息的情况下进行安全比较是非常容易的。
piedar

484

没有内置的方法可以做到这一点。您可以使用以下表达式:

(date1 > date2 ? date1 : date2)

找到两者中的最大值。

您可以编写一种通用方法来进行计算MinMax针对任何类型(只要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示例投票。
Oundless 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;
    }
}

这样可以使日期具有不同的“种类”,并返回传入的实例(不返回由Ticks或Millsseconds构造的新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()部分呢?
戴维·蒂伦

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);

哦,天才!这样,我不必每次都比较,而仅在处理完数据之后一次。非常感谢你!
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),但我不知道该怎么做...
扎克·史密斯

@ZachSmith您不能重载DateTime类,因为它不是局部的。也许我们可以使用DateTimeHelper.Max(dt1,dt2)
shtse8 '18

@ shtse8-重载是什么意思?我在考虑添加扩展方法。但是自那以后就知道,没有实例化实例是无法完成的。听起来您在说添加扩展方法是一种重载形式?我从来没有考虑过..那是正确的吗?现在我考虑一下...过载到底是什么意思?
扎克·史密斯

@ZachSmith哦,我想您要添加一个名为“ DateTime.MaxOf(dt1,dt2)”的扩展名,就像基于日期时间静态成员的“ DateTime.Now”一样。
shtse8

-2

现在有了LINQ,您可以使用两个值(DateTimes,TimeSpans等)创建一个数组,然后使用.Max()扩展方法。

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

它读起来很不错,它与Max一样高效,并且可以重复使用两个以上的比较值。

下面担心.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
问题被标记为.NET而不是Javascript
hawbsl

抱歉,没有注意到.NET。无论如何,我们可以在客户端找到最短日期并将其发送到服务器。
谢尔盖·苏沃洛夫

4
您假设我们在谈论asp,但不一定正确。计算客户端的差异也将是非常愚蠢的,因为存在更多的风险(禁用JavaScript),会产生不必要的流量并且会(取决于网络速度)变慢
jalgames 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.