Dies ist wahrscheinlich eine dumme Frage, aber ich kann es nicht herausfinden. Ich vergleiche die LastWriteTime von zwei Dateien, dies schlägt jedoch immer fehl, da für die aus dem Netz heruntergeladene Datei immer Millisekunden auf 0 gesetzt sind und meine Originaldatei einen tatsächlichen Wert hat. Gibt es eine einfache Möglichkeit, die Millisekunden beim Vergleich zu ignorieren?
Hier ist meine Funktion:
//compare file's dates
public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
{
DateTime dtOrig = File.GetLastWriteTime(strOrigFile);
DateTime dtNew = File.GetLastWriteTime(strDownloadedFile);
if (dtOrig == dtNew)
return true;
else
return false;
}
Danke im Voraus
Antworten:
Erstellen Sie einen neuen DateTime-Wert, wobei die Millisekunden-Komponente auf 0 gesetzt ist:
quelle
DateTime
Mikrosekunden ungleich Null sind. Siehe die Antworten von @ PeterIvan oder @ DeanChalk.Ich empfehle Ihnen eine Erweiterungsmethode:
public static DateTime TrimMilliseconds(this DateTime dt) { return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, 0, dt.Kind); }
dann ist es nur:
if (dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds())
quelle
DateTimeKind
auch, indem Siedt.Kind
am Ende von ctor hinzufügenVorsicht ist geboten, wenn
dt
die Mikrosekunden ungleich Null (Millisekunden) sind. Es reicht nicht aus, nur Millisekunden auf Null zu setzen.Um Millis und darunter auf Null zu setzen (und einen erfolgreichen Vergleich zu erhalten), wäre der Code:
dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000
quelle
dt.Kind
. Ich weiß , dass es das gleiche in allen Fällen gibt, aber für mich ist es natürlich zu Verwendungdt = dt.AddTicks(-(dt.Ticks % TimeSpan.TicksPerSecond));
, dh Nutzung%
Operator zuerst, und dann negiert. Das liegt daran%
, dass mir das Verhalten mit einem negativen ersten Operanden etwas verwirrend erscheint. Deshalb bevorzuge ich meine Version, in%
der zwei positive Operanden bearbeitet werden.a
undb
darf nicht deklariert werdenconst
):long a = long.MinValue; long b = 10L; long x = (-a) % b; long y = -(a % b); long z = -a % b;
Hier ist der Wert vonx
negativ, weil die Negation von wiedera
ergibta
und ein negativer Wert%
-ed auf einem positiven Wert einen negativen Wert ergibt. Aber der Wert vony
ist positiv, weil wir diesmal ein negatives Ergebnis zwischen-10
und negieren0
, und das ergibt eine positive Zahl. Jetzt schauz
es dir an!TimeSpan difference = dtNew - dtOrig; if (difference >= TimeSpan.FromSeconds(1)) { ... }
quelle
Sie können sie subtrahieren, um eine zu erhalten
TimeSpan
.Dann benutze
TimeSpan.totalSeconds()
quelle
Dies ist ein Overkill für ein einzelnes Abschneiden. Wenn Sie jedoch mehrere und verschiedene Typen haben, können Sie dies mithilfe der folgenden allgemeinen Erweiterungsmethode tun:
Allgemeiner Verwenden Sie die Erweiterungsmethode:
public static DateTime TruncateTo(this DateTime dt, DateTruncate TruncateTo) { if (TruncateTo == DateTruncate.Year) return new DateTime(dt.Year, 0, 0); else if (TruncateTo == DateTruncate.Month) return new DateTime(dt.Year, dt.Month, 0); else if (TruncateTo == DateTruncate.Day) return new DateTime(dt.Year, dt.Month, dt.Day); else if (TruncateTo == DateTruncate.Hour) return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0); else if (TruncateTo == DateTruncate.Minute) return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0); else return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second); } public enum DateTruncate { Year, Month, Day, Hour, Minute, Second }
quelle
public static DateTime TruncateTo(this DateTime dt, long truncateResolution) { return dt.AddTicks(-(dt.Ticks % truncateResolution)); }
. Viel kürzer und klarer. Dann verwenden Sie wie folgt:DateTime dtSecs = DateTime.Now.TruncateTo(TimeSpan.TicksPerSecond); DateTime dtHrs = DateTime.Now.TruncateTo(TimeSpan.TicksPerHour);
und so weiter. Sie können sogar auf seltsamere Auflösungen kürzen, z. B. ein Vielfaches von 3 Stunden (3 * TimeSpan.TicksPerHour
).Eine Möglichkeit wäre, neue Daten zu erstellen und das Jahr, den Monat, den Tag, die Stunde, die Minute und die Sekunde in den Konstruktor einzugeben. Alternativ können Sie einfach jeden Wert einzeln vergleichen.
quelle
Hier ist der einfachste Weg, dies zu tun. Sie können steuern,
precision
wie Sie möchten.bool AreEqual(DateTime a, DateTime b, TimeSpan precision) { return Math.Abs((a - b).TotalMilliseconds) < precision.TotalMilliseconds; }
und die Verwendung ist ziemlich selbsterklärend
var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));
quelle
Ether setzt die Millisekunden in Ihrer anderen Datumszeit auf Null oder subtrahiert ein Datum vom anderen und überprüft einfach die
TotalMinutes
Eigenschaft der resultierenden Zeitspanne.quelle
Sie können eine Erweiterungsmethode erstellen, mit der die Millisekunden für ein DateTime-Objekt auf Null gesetzt werden
public static DateTime ZeroMilliseconds(this DateTime value) { return new DateTime(value.Year, value.Month, value.Day, value.Hours, value.Minutes, value.Seconds); }
Dann in Ihrer Funktion
if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()) return true; else return false;
quelle
DateTime
Vergleichen Sie nur relevante Teile, anstatt nicht relevante DateTime-Teile durch Erstellen neuer s zu kürzen :public static class Extensions { public static bool CompareWith(this DateTime dt1, DateTime dt2) { return dt1.Second == dt2.Second && // 1 of 60 match chance dt1.Minute == dt2.Minute && // 1 of 60 chance dt1.Day == dt2.Day && // 1 of 28-31 chance dt1.Hour == dt2.Hour && // 1 of 24 chance dt1.Month == dt2.Month && // 1 of 12 chance dt1.Year == dt2.Year; // depends on dataset } }
Ich habe die Antwort von Dean Chalk als Grundlage für den Leistungsvergleich genommen. Die Ergebnisse sind:
CompareWith
ist etwas schneller alsTrimMilliseconds
bei gleichen DatenCompareWith
ist ein schneller als Daten sind nicht gleichMein Perf-Test (im Konsolenprojekt ausführen)
static void Main(string[] args) { var dtOrig = new DateTime(2018, 03, 1, 10, 10, 10); var dtNew = dtOrig.AddMilliseconds(100); //// perf run for not-equal dates comparison //dtNew = dtNew.AddDays(1); //dtNew = dtNew.AddMinutes(1); int N = 1000000; bool isEqual = false; var sw = Stopwatch.StartNew(); for (int i = 0; i < N; i++) { // TrimMilliseconds comes from // https://stackoverflow.com/a/7029046/1506454 // answer by Dean Chalk isEqual = dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds(); } var ms = sw.ElapsedMilliseconds; Console.WriteLine("DateTime trim: " + ms + " ms"); sw = Stopwatch.StartNew(); for (int i = 0; i < N; i++) { isEqual = dtOrig.CompareWith(dtNew); } ms = sw.ElapsedMilliseconds; Console.WriteLine("DateTime partial compare: " + ms + " ms"); Console.ReadKey(); }
quelle
Wirf sortierbare Strings und vergleiche. einfach und gut laufen.
return string.Compare(dtOrig.ToString("s"), dtNew.ToString("s"), StringComparison.Ordinal) == 0;
quelle
Der einfachste Weg, die Zeit zu verkürzen, besteht darin, sie zu formatieren und die gewünschten Einheiten zu analysieren:
var myDate = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));
DOKs Methode neu geschrieben
public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile) { DateTime dtOrig = DateTime.Parse(File.GetLastWriteTime(strOrigFile).ToString("MM/dd/yyyy hh:mm:ss")); DateTime dtNew = DateTime.Parse(File.GetLastWriteTime(strDownloadedFile).ToString("MM/dd/yyyy hh:mm:ss")); if (dtOrig == dtNew) return true; else return false; }
quelle
DateTime.ParseExact
damit dies auch nur aus der Ferne zuverlässig ist.Ich weiß nicht, warum fast alle Programmierer zusätzliche Zeilen benötigen, um einen Bool-Wert von einer Funktion mit einem Bool-Ausdruck zurückzugeben.
stattdessen
if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()) return true; else return false;
Sie können immer nur verwenden
return dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()
Wenn der Ausdruck wahr ist, wird true zurückgegeben, andernfalls false.
quelle