C# 如何截断 .NET DateTime 的毫秒数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1004698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to truncate milliseconds off of a .NET DateTime
提问by Jeff Putz
I'm trying to compare a time stamp from an incoming request to a database stored value. SQL Server of course keeps some precision of milliseconds on the time, and when read into a .NET DateTime, it includes those milliseconds. The incoming request to the system, however, does not offer that precision, so I need to simply drop the milliseconds.
我正在尝试将来自传入请求的时间戳与数据库存储值进行比较。SQL Server 当然在时间上保持一定的毫秒精度,当读入 .NET DateTime 时,它包括这些毫秒。然而,系统的传入请求并没有提供这种精度,所以我需要简单地删除毫秒。
I feel like I'm missing something obvious, but I haven't found an elegant way to do it (C#).
我觉得我错过了一些明显的东西,但我还没有找到一种优雅的方法来做到这一点(C#)。
采纳答案by Joe
The following will work for a DateTime that has fractional milliseconds, and also preserves the Kind property (Local, Utc or Undefined).
以下内容适用于具有小数毫秒的 DateTime,并且还保留了 Kind 属性(Local、Utc 或 Undefined)。
DateTime dateTime = ... anything ...
dateTime = new DateTime(
dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond),
dateTime.Kind
);
or the equivalent and shorter:
或等效且更短的:
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));
This could be generalized into an extension method:
这可以推广为一个扩展方法:
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));
}
which is used as follows:
其用法如下:
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
...
回答by chris.w.mclean
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
回答by benPearce
var date = DateTime.Now;
date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
回答by Bob
Instead of dropping the milliseconds then comparing, why not compare the difference?
与其放弃毫秒然后比较,为什么不比较差异呢?
DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;
or
或者
TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
回答by Diadistis
Less obvious but more than 2 times faster :
不太明显,但快了 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);
回答by Joe
Regarding Diadistis response. This worked for me, except I had to use Floor to remove the fractional part of the division before the multiplication. So,
关于 Diadistis 的反应。这对我有用,除了我必须在乘法之前使用 Floor 删除除法的小数部分。所以,
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
becomes
变成
d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
I would have expected the division of two Long values to result in a Long, thus removing the decimal part, but it resolves it as a Double leaving the exact same value after the multiplication.
我原以为两个 Long 值的除法会产生一个 Long,从而删除小数部分,但它将其解析为 Double ,在乘法后留下完全相同的值。
Eppsy
爱普西
回答by Sky Sanders
Here is an extension method based on a previous answer that will let you truncate to any resolution...
这是基于先前答案的扩展方法,可让您截断为任何分辨率...
Usage:
用法:
DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond);
DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)
Class:
班级:
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);
}
}
回答by HerbalMart
2 Extension methods for the solutions mentioned above
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;
}
usage:
用法:
bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
回答by KingPong
Sometimes you want to truncate to something calendar-based, like year or month. Here's an extension method that lets you choose any resolution.
有时你想截断到基于日历的东西,比如年或月。这是一种扩展方法,可让您选择任何分辨率。
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");
}
}
回答by Sergio Cabral
A way for easy reading is...
一种轻松阅读的方法是...
//Remove milliseconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);
And more...
和更多...
//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...