Эквивалент Math.Min & Math.Max для дат?
Какой самый быстрый и простой способ получить значение Min (или Max) между двумя датами? Есть ли эквивалент Math.Min(& Math.Max) для дат?
Я хочу сделать что-то вроде:
if (Math.Min(Date1, Date2) < MINIMUM_ALLOWED_DATE) {
//not allowed to do this
}
Очевидно, что указанный выше Math.Min не работает, потому что это даты.
Ответы
Ответ 1
Не существует перегрузки для значений DateTime, но вы можете получить длинное значение Ticks
, которое содержит значения, сравнить их и затем создать новое значение DateTime из результата:
new DateTime(Math.Min(Date1.Ticks, Date2.Ticks))
(Обратите внимание, что структура DateTime также содержит свойство Kind
, которое не сохраняется в новом значении. Обычно это не проблема, если сравнивать значения DateTime разных типов, сравнение в любом случае не имеет смысла. )
Ответ 2
Нет встроенного метода для этого. Вы можете использовать выражение:
(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()
Ответ 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();
Ответ 4
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, построенный из Ticks или Milliseconds).
[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);
}
Обратите внимание, что этот тест завершится неудачей к востоку от Гринвича...
Ответ 5
Если вы хотите называть его более похожим на Math.Max, вы можете сделать что-то вроде этого очень короткого тела выражения:
public static DateTime Max(params DateTime[] dates) => dates.Max();
[...]
var lastUpdatedTime = DateMath.Max(feedItemDateTime, assemblyUpdatedDateTime);
Ответ 6
Подход 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();
Ответ 7
Как насчет метода расширения DateTime
?
public static DateTime MaxOf(this DateTime instance, DateTime dateTime)
{
return instance > dateTime ? instance : dateTime;
}
Использование:
var maxDate = date1.MaxOf(date2);
Ответ 8
Теперь, когда у нас есть LINQ, вы можете создать массив с двумя значениями (DateTimes, TimeSpans и т.д.), А затем использовать метод расширения .Max().
var values = new[] { Date1, Date2 };
var max = values.Max();
Он хорошо читается, настолько эффективен, насколько может быть Макс, и его можно использовать более чем для двух значений сравнения.
Вся проблема, описанная ниже, беспокоит. Вид - это большое дело... но я избегаю этого, никогда не работая по местному времени. Если у меня есть что-то важное в отношении времени, я всегда работаю в UTC, даже если для этого нужно больше работать.
Ответ 9
Вы можете сделать следующее, используя LINQ.Min():
if (new DateTime[]{Date1, Date2}.Min() < MINIMUM_ALLOWED_DATE) {
//not allowed to do this
}
Ответ 10
// 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/