如何截断.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)
用TicksPerMinute
replace为一分钟。
如果你的代码是性能敏感的,要谨慎
new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)
我的应用程序在System.DateTime.GetDatePart中花费CPU时间的12%。
- 为什么ReadOnlyObservableCollection.CollectionChanged不公开?
- 如何检查默认的DateTime值?
- 如何将CSS类属性添加到razor的文本框?
- 我应该如何投射在VB.NET?
- 从扩展方法的ArgumentNullException或NullReferenceException?
- 如何获得.NET(C#)中的UserControl的HTML输出?
- 如何从Visual Studio命令提示符以外的命令行运行regasm.exe?
- 解密.NET clr20r3exception参数P1..P10
- 在使用System.DirectoryServices时尝试访问卸载的AppDomain