如何截断.NET DateTime的毫秒数

我试图比较一个传入请求的时间戳到一个数据库存储的值。 SQL Server当然会保持一些毫秒级的精度,当读入.NET DateTime时,它包含那些毫秒。 然而,对系统的传入请求不提供这种精度,所以我需要简单地减less毫秒。

我觉得我错过了一些明显的东西,但我还没有find一个优雅的方式来做到这一点(C#)。

以下将适用于具有分数毫秒的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">eg 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); 

而不是下降毫秒然后比较,为什么不比较差异?

 DateTime x; DateTime y; bool areEqual = (xy).TotalSeconds == 0; 

要么

 TimeSpan precision = TimeSpan.FromSeconds(1); bool areEqual = (xy).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); 

有时候,你想截断日历为基础的东西,如年份或月份。 这里有一个扩展方法,可以让你select任何分辨率。

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

关于Diadistis的回应。 这对我很有效,除了我必须使用Floor来删除乘法之前的小数部分。 所以,

 d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond); 

 d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond); 

我会期望两个Long值的除法导致一个Long,从而删除小数部分,但它将其parsing为一个Double,在乘法之后保留完全相同的值。

Eppsy

2上述解决scheme的扩展方法

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

//定义string传递参数dd-mmm-yyyy返回24-feb-2016

或在文本框中显示

 txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy"); 

//放在PageonLoad上

简单…

 //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... 

为了圆满到第二个:

 dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond) 

TicksPerMinutereplace为一分钟。


如果你的代码是性能敏感的,要谨慎

 new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second) 

我的应用程序在System.DateTime.GetDatePart中花费CPU时间的12%。