Как усечь миллисекунды от a.NET DateTime
Я пытаюсь сравнить отметку времени от входящего запроса к сохраненному значению базы данных. SQL Server, конечно, сохраняет некоторую точность миллисекунд по времени, и при чтении в .NET DateTime он включает эти миллисекунды. Входящий запрос к системе, однако, не предлагает такой точности, поэтому мне нужно просто отбросить миллисекунды.
Я чувствую, что мне не хватает чего-то очевидного, но я не нашел элегантный способ сделать это (C#).
13 ответов:
следующее будет работать для DateTime, который имеет дробные миллисекунды, а также сохраняет свойство Kind (Local, Utc или Undefined).
DateTime dateTime = ... anything ... dateTime = new DateTime( dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond), dateTime.Kind );или эквивалент и короче:
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));Это можно обобщить в метод расширения:
public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan) { if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks)); }, который используется следующим образом:
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);
вот метод расширения, основанный на предыдущем ответе, который позволит вам усечь любое разрешение...
использование:
DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond); DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)класс:
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 x; DateTime y; bool areEqual = (x-y).TotalSeconds == 0;или
TimeSpan precision = TimeSpan.FromSeconds(1); bool areEqual = (x-y).Duration() < precision;
менее очевидны, но более чем в 2 раза быстрее :
// 10000000 runs DateTime d = DateTime.Now; // 484,375ms d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond); // 1296,875ms d = d.AddMilliseconds(-d.Millisecond);
иногда вы хотите, чтобы усечь что-то на основе календаря, как год или месяц. Вот метод расширения, который позволяет выбрать любое разрешение.
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"); } }
простой...
//Remove milliseconds DateTime date = DateTime.Now; date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);и многое другое...
//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...
по поводу ответа Diadistis. Это сработало для меня, за исключением того, что мне пришлось использовать пол, чтобы удалить дробную часть деления перед умножением. Итак,
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);становится
d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);Я ожидал бы, что деление двух длинных значений приведет к длинному, тем самым удаляя десятичную часть, но он разрешает ее как двойную, оставляя точно такое же значение после умножения.
Eppsy
2 методы расширения для решений, упомянутых выше
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; }использование:
bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
DateID.Text = DateTime.Today.ToShortDateString(); Use ToShortDateString() //Date 2-02-2016 Use ToShortDateString() // TimeИ
ToLongDateString() // its show 19 February 2016.: P
Новый Метод
String Date = DateTime.Today.ToString("dd-MMM-yyyy");/ / определить Строковый параметр передачи DD-mmm-yyyy return 24-feb-2016
или показано на текстовом поле
txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");/ / put on PageonLoad
округлить до второго:
dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond)заменить на
TicksPerMinuteокруглить до минуты.
Если ваш код чувствителен к производительности, будьте осторожны с
new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)мое приложение тратило 12% процессорного времени в
Comments