501 Stimmen

Äquivalent von Math.Min & Math.Max für Daten?

Wie kann ich am schnellsten und einfachsten den Minimalwert (oder Maximalwert) zwischen zwei Daten ermitteln? Gibt es eine Entsprechung zu Math.Min (& Math.Max) für Datumsangaben?

Ich möchte etwas tun wie:

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

Offensichtlich funktioniert die obige Math.Min nicht, weil es sich um Datumsangaben handelt.

20voto

user450 Punkte 405
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;
    }
}

Dadurch können die Datumsangaben unterschiedliche "Arten" haben, und es wird die Instanz zurückgegeben, die übergeben wurde (und nicht eine neue DateTime, die aus Ticks oder Millisekunden konstruiert wurde).

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

Beachten Sie, dass dieser Test östlich von Greenwich fehlschlagen würde...

8voto

Oundless Punkte 5255

Wie wäre es mit einem DateTime Erweiterungsmethode?

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

Uso:

var maxDate = date1.MaxOf(date2);

2voto

ralofpatel Punkte 39

Fügen Sie diese beiden Methoden in eine Utility-Klasse ein und verwenden Sie sie, um Min/Max einer beliebigen Anzahl von DateTimes zu ermitteln:

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

-1voto

Craig Brunetti Punkte 489

Da wir nun LINQ haben, können Sie ein Array mit Ihren beiden Werten (DateTimes, TimeSpans, was auch immer) erstellen und dann die Erweiterungsmethode .Max() verwenden.

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

Es liest sich gut, es ist so effizient wie Max sein kann, und es ist wiederverwendbar für mehr als 2 Vergleichswerte.

Das ganze Problem unter der Sorge um .Kind ist eine große Sache... aber ich vermeide das, indem ich nie in lokalen Zeiten arbeite, niemals. Wenn ich etwas Wichtiges in Bezug auf Zeiten habe, arbeite ich immer in UTC, auch wenn es mehr Arbeit bedeutet, dorthin zu gelangen.

-2voto

imstoopid Punkte 9

Mit Date.parse() können wir Daten in primitive Zahlen umwandeln und dann Math.min() und Math.max() für die Verarbeitung und Speicherung verwenden. Mit diesem Primitiv können wir jedes beliebige Format wiedergeben, das wir wollen. Es ist ein 2-3 Schritte Prozess, aber wir praktisch eliminiert das Risiko von funky Ergebnisse zu erhalten.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X