日期的 Math.Min 和 Math.Max 等价物?
Posted
技术标签:
【中文标题】日期的 Math.Min 和 Math.Max 等价物?【英文标题】:Equivalent of Math.Min & Math.Max for Dates? 【发布时间】:2010-12-31 09:58:45 【问题描述】:获取两个日期之间的最小值(或最大值)的最快和最简单的方法是什么?日期是否有等效于 Math.Min (& Math.Max) 的方法?
我想做这样的事情:
if (Math.Min(Date1, Date2) < MINIMUM_ALLOWED_DATE)
//not allowed to do this
显然,上面的 Math.Min 不起作用,因为它们是日期。
【问题讨论】:
【参考方案1】:没有内置的方法可以做到这一点。您可以使用表达式:
(date1 > date2 ? date1 : date2)
求两者中的最大值。
您可以编写一个通用方法来计算任何类型的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()
【讨论】:
【参考方案2】:DateTime 值没有重载,但您可以获取值包含的长值 Ticks
,比较它们,然后从结果中创建一个新的 DateTime 值:
new DateTime(Math.Min(Date1.Ticks, Date2.Ticks))
(请注意,DateTime 结构还包含一个 Kind
属性,该属性不会保留在新值中。这通常不是问题;如果您比较不同类型的 DateTime 值,则无论如何比较都没有意义。 )
【讨论】:
在我看来,这似乎最接近 Math.Min 的单行替换/等效项,但为了完整性,其他答案也很棒 -,您完全失去了原始System.DateTime
-instance 的所有信息(除了记号)
@AndreasNiedermair:如果您要比较不同类型的日期,无论如何您都不能直接比较它们。我已经在答案中介绍了这一点。
@Iain:你总是可以比较它们,但是如果你比较不可比较的值,结果是没有用的。它与任何其他不可比较的值相同,例如比较以公里为单位的距离和以英里为单位的距离;您可以很好地比较这些值,但这并不意味着什么。
-1 对 Kind 挥手致意。如@user450 的回答所示,很容易将两个时间都转换为 UTC 并安全地比较它们而不会丢弃信息。【参考方案3】:
怎么样:
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();
【讨论】:
第一种方法,空检查后可以是return values.Min();
。【参考方案4】:
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();
【讨论】:
【参考方案5】:如果你想调用它更像 Math.Max,你可以做这样一个非常短的表达式体:
public static DateTime Max(params DateTime[] dates) => dates.Max();
[...]
var lastUpdatedTime = DateMath.Max(feedItemDateTime, assemblyUpdatedDateTime);
【讨论】:
【参考方案6】: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 或 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);
请注意,此测试在格林威治以东会失败...
【讨论】:
为什么不直接删除 ToUniversalTime() 部分?【参考方案7】: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 - 重载是什么意思?我正在考虑添加扩展方法。但后来了解到,如果没有实例化实例,就无法做到这一点。听起来您是在说添加扩展方法是一种重载形式?我从来没有考虑过..这是正确的吗?现在我想起来了……重载到底是什么意思?
@ZachSmith 哦,我以为您正在添加一个名为“DateTime.MaxOf(dt1, dt2)”的扩展名,就像基于 DateTime 静态成员的“DateTime.Now”一样。【参考方案8】:
将这两个方法放在一个 Utility 类中,并使用它们来获取任意数量的 DateTimes 的 Min/Max:
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);
【讨论】:
【参考方案9】:现在我们有了 LINQ,您可以使用两个值(DateTimes、TimeSpans 等)创建一个数组,然后使用 .Max() 扩展方法。
var values = new[] Date1, Date2 ;
var max = values.Max();
它读起来很好,它的效率与 Max 一样高,并且可重复用于 2 个以上的比较值。
下面担心 .Kind 的整个问题是个大问题……但我避免了这种情况,因为我从来没有在当地时间工作过。如果我有重要的时间方面的事情,我总是在 UTC 工作,即使这意味着需要更多的工作才能到达那里。
【讨论】:
我的答案副本【参考方案10】:我们可以使用 Date.parse() 将日期转换为 Number 原语,然后我们可以使用 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()]);
【讨论】:
问题是关于C#的 我的错.. 没看到。我很笨【参考方案11】:// 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/
【讨论】:
很好的建议(真的),但没有描述很难找到为什么它是好的。请描述诀窍在哪里。没有描述,它只是一段代码,而不是答案。 问题被标记为 .NET 而不是 Javascript 抱歉,没有注意到 .NET。无论如何,我们可以在客户端找到最小日期并将其发送到服务器。 你假设我们说的是asp,这不一定对。在客户端上计算差异也是非常愚蠢的,因为存在更多风险(禁用 JavaScript),它会产生不必要的流量并且(取决于网络速度)会变慢 创建一个运行在node.js中的datecomparison微服务,然后你就可以调用它来回答原问题了以上是关于日期的 Math.Min 和 Math.Max 等价物?的主要内容,如果未能解决你的问题,请参考以下文章