相当于数学。分钟,数学。Max for Dates?

获得两个日期之间的最小值(或最大值)的最快和最简单的方法是什么?有数学等价物吗?Min (,Math.Max)约会?

我想做的事情是:

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

显然上面的数学。Min没用,因为它们是日期。

184059 次浏览

没有内置的方法来做这个。你可以使用这样的表达:

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

如何:

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

DateTime值没有重载,但是你可以获得这些值包含的长值Ticks,比较它们,然后从结果中创建一个新的DateTime值:

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

(注意,DateTime结构还包含Kind属性,它不会保留在新值中。这通常不是问题;如果你比较不同类型的DateTime值,这种比较是没有意义的。)

// 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/

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

这允许日期有不同的“种类”,并返回被传入的实例(不返回一个由tick或Milliseconds构造的新的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);
}

请注意,该测试在格林威治以东将失败。

如果你想使用Linq.Max(),但更像Math.Max,你可以这样做,非常短的表达式体:

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

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

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

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

它读起来很好,它和Max一样高效,并且它可以用于两个以上的比较值。

下面担心的整个问题。善良是一件大事…但为了避免这种情况,我从不在当地时间工作。如果我有一些关于时间的重要事情,我总是用UTC工作,即使这意味着要做更多的工作。

DateTime扩展方法怎么样?

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

用法:

var maxDate = date1.MaxOf(date2);

将这两个方法放在一个Utility类中,并使用它们来获取任意数量的DateTimes的最小/最大值:

public static DateTime Min(params DateTime[] dates)
{
if (dates.Length == 1) return dates[0];


long minTicks = dates[0].Ticks;


for (int i = 1; i < dates.Length; i++)
{
minTicks = Math.Min(minTicks, dates[i].Ticks);
}


return new DateTime(minTicks);
}


public static DateTime Max(params DateTime[] dates)
{
if (dates.Length == 1) return dates[0];


long maxTicks = dates[0].Ticks;


for (int i = 1; i < dates.Length; i++)
{
maxTicks = Math.Max(maxTicks, dates[i].Ticks);
}


return new DateTime(maxTicks);
}
我们可以使用Date.parse()将日期转换为数字原语,然后我们可以使用Math.min()和Math.max()进行处理和存储。有了这个原语,我们可以以任何我们想要的格式呈现。 这是一个2-3步的过程,但我们实际上消除了得到奇怪结果的风险

const unixTimeZero = Date.parse('01 Jan 1970 00:00:00 GMT');
const javaScriptRelease = Date.parse('04 Dec 1995 00:12:00 GMT');
const today = Date.parse(new Date());
const d1 = Date.parse(new Date("2004-02-01"));
const d2 = Date.parse(new Date("2017-01"));
const d3 = Date.parse(new Date("2018"))
const t = [unixTimeZero, d1, d2, d3, today, javaScriptRelease];
const min = Math.min(...t)
const max = Math.max(...t)
console.log(unixTimeZero); // expected output: 0
console.log(javaScriptRelease); // expected output: 818035920000
console.log(today);
console.log(t);
console.log(["unixMin: " + min, "earliestDate: " + new Date(min).toUTCString()]);
console.log(["unixMax: " + max, "latestDate: " + new Date(max).toDateString()]);