Ich versuche, einen Zeitstempel aus einer eingehenden Anforderung mit einem in der Datenbank gespeicherten Wert zu vergleichen. SQL Server natürlich hält einige Präzision von Millisekunden auf die Zeit, und wenn in eine .NET DateTime gelesen, es enthält diese Millisekunden. Die eingehende Anforderung an das System bietet jedoch nicht diese Präzision, so dass ich die Millisekunden einfach weglassen muss.
Ich habe das Gefühl, dass ich etwas Offensichtliches übersehe, aber ich habe keinen eleganten Weg gefunden, es zu tun (C#).
Das Folgende funktioniert für eine DateTime, die Bruchteile von Millisekunden hat und auch die Kind-Eigenschaft (Local, Utc oder Undefined) beibehält.
DateTime dateTime = ... anything ...
dateTime = new DateTime(
dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond),
dateTime.Kind
);
oder das Äquivalent und kürzer:
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));
Dies könnte zu einer Erweiterungsmethode verallgemeinert werden:
public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException
if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) return dateTime; // do not modify "guard" values
return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}
die wie folgt verwendet wird:
dateTime = dateTime.Truncate(TimeSpan.FromMilliseconds(1)); // Truncate to whole ms
dateTime = dateTime.Truncate(TimeSpan.FromSeconds(1)); // Truncate to whole second
dateTime = dateTime.Truncate(TimeSpan.FromMinutes(1)); // Truncate to whole minute
...
var date = DateTime.Now;
date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
Hier ist eine Erweiterungsmethode, die auf einer vorherigen Antwort basiert, mit der Sie auf jede beliebige Auflösung kürzen können...
Verwendung:
DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond);
DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)
Klasse:
public static class DateTimeUtils
{
/// <summary>
/// <para>Truncates a DateTime to a specified resolution.</para>
/// <para>A convenient source for resolution is TimeSpan.TicksPerXXXX constants.</para>
/// </summary>
/// <param name="date">The DateTime object to truncate</param>
/// <param name="resolution">e.g. to round to nearest second, TimeSpan.TicksPerSecond</param>
/// <returns>Truncated DateTime</returns>
public static DateTime Truncate(this DateTime date, long resolution)
{
return new DateTime(date.Ticks - (date.Ticks % resolution), date.Kind);
}
}
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
Anstatt die Millisekunden zu vernachlässigen und dann zu vergleichen, warum nicht die Differenz vergleichen?
DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;
oder
TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
Manchmal möchten Sie auf etwas kalenderbasiert kürzen, wie Jahr oder Monat. Hier's eine Erweiterungsmethode, mit der Sie jede beliebige Auflösung wählen können.
public enum DateTimeResolution
{
Year, Month, Day, Hour, Minute, Second, Millisecond, Tick
}
public static DateTime Truncate(this DateTime self, DateTimeResolution resolution = DateTimeResolution.Second)
{
switch (resolution)
{
case DateTimeResolution.Year:
return new DateTime(self.Year, 1, 1, 0, 0, 0, 0, self.Kind);
case DateTimeResolution.Month:
return new DateTime(self.Year, self.Month, 1, 0, 0, 0, self.Kind);
case DateTimeResolution.Day:
return new DateTime(self.Year, self.Month, self.Day, 0, 0, 0, self.Kind);
case DateTimeResolution.Hour:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerHour));
case DateTimeResolution.Minute:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMinute));
case DateTimeResolution.Second:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerSecond));
case DateTimeResolution.Millisecond:
return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMillisecond));
case DateTimeResolution.Tick:
return self.AddTicks(0);
default:
throw new ArgumentException("unrecognized resolution", "resolution");
}
}
Weniger offensichtlich, aber mehr als 2 Mal schneller :
// 10000000 runs
DateTime d = DateTime.Now;
// 484,375ms
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
// 1296,875ms
d = d.AddMilliseconds(-d.Millisecond);
Zur Abrundung auf die Sekunde:
dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond)
Ersetzen Sie durch TicksPerMinute
, um auf die Minute abzurunden.
Wenn Ihr Code leistungsabhängig ist, seien Sie vorsichtig bei
new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)
Meine Anwendung verbrachte 12 % der CPU-Zeit in [System.DateTime.GetDatePart] (https://referencesource.microsoft.com/#mscorlib/system/datetime.cs,ff06f271f088f1a8).
Eine Möglichkeit zum einfachen Lesen ist...
//Remove milliseconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);
Und noch mehr...
//Remove seconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm"), "yyyy-MM-dd HH:mm", null);
//Remove minutes
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH"), "yyyy-MM-dd HH", null);
//and go on...
2 Erweiterungsmethoden für die oben genannten Lösungen
public static bool LiesAfterIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
{
DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);
return thisDate > compareDate;
}
public static bool LiesAfterOrEqualsIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
{
DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);
return thisDate >= compareDate;
}
Verwendung:
bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
Bezüglich der Reaktion von Diadistis. Das hat bei mir funktioniert, außer dass ich Floor verwenden musste, um den Bruchteil der Division vor der Multiplikation zu entfernen. Also,
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
wird
d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
Ich hätte erwartet, dass die Division von zwei Long-Werten ein Long ergibt, wodurch der Dezimalteil entfernt wird, aber es wird als Double aufgelöst, so dass nach der Multiplikation genau der gleiche Wert übrig bleibt.
Eppsy
Neue Methode
String Date = DateTime.Today.ToString("dd-MMM-yyyy");
// define String pass parameter dd-mmm-yyyyyy return 24-feb-2016
Oder im Textfeld angezeigt
txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");
// auf PageonLoad setzen
DateID.Text = DateTime.Today.ToShortDateString();
Use ToShortDateString() //Date 2-02-2016
Use ToShortDateString() // Time
Und unter Verwendung von
ToLongDateString() // its show 19 February 2016.
:P
In meinem Fall wollte ich die Zeitspanne vom datetimePicker-Tool sparen, ohne die Sekunden und Millisekunden zu sparen, und hier ist die Lösung.
Konvertieren Sie zunächst den datetimePicker.value in das von Ihnen gewünschte Format, welches meines ist "HH:mm" dann konvertieren Sie ihn zurück in TimeSpan.
var datetime = datetimepicker1.Value.ToString("HH:mm");
TimeSpan timeSpan = Convert.ToDateTime(datetime).TimeOfDay;
Ich weiß, dass die Antwort ziemlich spät kommt, aber der beste Weg, Millisekunden loszuwerden, ist
var currentDateTime = DateTime.Now.ToString("s");
Versuchen Sie, den Wert der Variablen auszudrucken, es wird die Datums-Uhrzeit ohne Millisekunden angezeigt.