¿Equivalente a Math.Min y Math.Max ​​para fechas?

Resuelto hawbsl asked hace 14 años • 11 respuestas

¿Cuál es la forma más rápida y sencilla de obtener el valor mínimo (o máximo) entre dos fechas? ¿Existe un equivalente a Math.Min (y Math.Max) para las fechas?

Quiero hacer algo como:

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

Obviamente el Math.Min anterior no funciona porque son fechas.

hawbsl avatar Dec 31 '09 20:12 hawbsl
Aceptado

No existe ningún método integrado para hacer eso. Puedes usar la expresión:

(date1 > date2 ? date1 : date2)

para encontrar el máximo de los dos.

Puede escribir un método genérico para calcular Mino Maxpara cualquier tipo (siempre que Comparer<T>.Defaultesté configurado adecuadamente):

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

También puedes usar LINQ:

new[]{date1, date2, date3}.Max()
Mehrdad Afshari avatar Dec 31 '2009 13:12 Mehrdad Afshari

No hay sobrecarga para los valores DateTime, pero puede obtener el valor largo Ticksque es lo que contienen los valores, compararlos y luego crear un nuevo valor DateTime a partir del resultado:

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

(Tenga en cuenta que la estructura DateTime también contiene una Kindpropiedad que no se conserva en el nuevo valor. Esto normalmente no es un problema; si compara valores DateTime de diferentes tipos, la comparación no tiene sentido de todos modos).

Guffa avatar Dec 31 '2009 13:12 Guffa

Linq.Min()/ Linq.Max()acercarse:

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(); 
Toshi avatar Jun 01 '2017 08:06 Toshi

Qué tal si:

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

Funciona con cualquier tipo que admita IComparable<T>o IComparable.

En realidad, con LINQ, otra alternativa es:

var min = new[] {x,y,z}.Min();
Marc Gravell avatar Dec 31 '2009 13:12 Marc Gravell

Si desea utilizar use Linq.Max()pero llamarlo más como Math.Max, puede hacer algo como este cuerpo de expresión muy corto:

public static DateTime Max(params DateTime[] dates) => dates.Max();
[...]
var lastUpdatedTime = DateMath.Max(feedItemDateTime, assemblyUpdatedDateTime);
R. Salisbury avatar May 12 '2017 11:05 R. Salisbury