#1 楼
以下内容将适用于具有小数毫秒的DateTime,并且还保留Kind属性(Local,Utc或Undefined)。br />
DateTime dateTime = ... anything ...
dateTime = new DateTime(
dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond),
dateTime.Kind
);
可以概括为扩展方法: />
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));
评论
尽管我会因为技术上的正确而为您提供此信息,但对于从SQL Server读取数据以与某些分布式数据(在我的情况下,基于Web的请求)进行比较的人们来说,这种解决方案的数量是不必要的。
–杰夫·普茨(Jeff Putz)
09年6月17日在21:33
真好显然,有人需要给DateTime类一些扩展方法以四舍五入到最接近的值,以便可以重新使用这种良好的编码类型。
–chris.w.mclean
09年6月17日在21:48
这是不太可能的,但是当ticks = 0时这种方法不会中断吗?
–淘汰赛
13年7月24日在13:12
@adotout,如果timeSpan参数为零,则上面的Truncate方法将引发DivideByZeroException,这是您的意思是“当滴答= 0时方法中断”吗?当timeSpan为零时,最好抛出ArgumentException。
–乔
13年7月24日在19:46
您是否应该真正忽略DateTime.MinValue和DataTime.MaxValue?如果有人明确使用DateTime.MaxValue.Truncate(TimeSpan.FromSeconds(1)),我希望它能完成锡盒上的说明。
– Alex
11月2日9:41
#2 楼
var date = DateTime.Now;
date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
评论
简洁明了,只需记住在构造函数的末尾添加“,date.Kind”,以确保您不会丢失重要的信息。
– JMcDaniel
2011年2月2日在15:59
对性能敏感代码中的此解决方案要谨慎。我的应用在System.DateTime.GetDatePart中花费了12%的CPU时间。
–上校恐慌
16-10-25在8:43
这很简单,但是比标记为最佳答案的问题要慢。并不是说这可能是瓶颈,但是它慢了大约7-8倍。
–乔纳斯(Jonas)
17年8月3日在23:33
“慢得多”的陈述并不正确,取决于运行时间,其差异在50%到100%之间。净4.7.2:0.35µs和0.62µs,核心3.1:0.18µs和0.12µs,即微秒(10 ^ -6秒)
– juwens
2月3日15:55
#3 楼
这是基于先前答案的扩展方法,可让您截断为任何分辨率...用法:
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);
}
}
评论
这是一个真正灵活且可重复使用的解决方案,简洁明了,不会太冗长。我的投票是最好的解决方案。
–Jaans
15年9月17日在11:21
您实际上不需要%操作数周围的括号。
– ErikE
16 Dec 9'在3:29
..但我认为这些括号增加了清晰度。
– Orion elenzil
17年5月27日下午5:21
#4 楼
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
评论
-1:仅在DateTime值不包含毫秒的分数时才有效。
–乔
09年6月17日在10:43
使用此方法导致我的某些单元测试失败:预期:2010-05-05 15:55:49.000但是是:2010-05-05 15:55:49.000。我猜是由于乔提到的关于毫秒的分数。
–塞斯·里诺(Seth Reno)
2010年5月5日20:57
不适用于序列化,例如2010-12-08T11:20:03.000099 + 15:00是输出,不能完全砍掉毫秒。
– joedotnot
2010-12-8在0:24
毫秒属性提供0到999(含)之间的整数。因此,如果手术前一天的时间是23:48:49.1234567,那么该整数将是123,手术后一天的时间是23:48:49.0004567。因此,它还没有被截断到整秒。
–杰普·斯蒂格·尼尔森(Jeppe Stig Nielsen)
13年8月24日在12:43
#5 楼
有时您希望将其截断为基于日历的内容,例如年或月。这是扩展方法,可让您选择任何分辨率。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");
}
}
#6 楼
为什么不比较毫秒而不是比较毫秒?DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;
或
TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
评论
第一个选项不起作用,因为TotalSeconds是双精度型;它还返回毫秒。
– Jowen
2010-6-10 10:21
比较差异不会得到截断然后比较的结果。例如。 5.900和6.100相距不到一秒,因此可以与您的方法进行比较。但是截断的值5和6不同。哪个合适取决于您的要求。
–乔
15年1月29日在11:46
#7 楼
不太明显,但快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);
评论
请注意,第二个选项d.AddMilliseconds(-d.Millisecond)不一定将DateTime精确地移到前一秒。 d.Ticks超出秒数的%TimeSpan.TicksPerMillisecond刻度(0到9,999之间的某个刻度)将保留。
– net
2012年9月12日于20:59
#8 楼
四舍五入到第二个:dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond)
用
TicksPerMinute
替换以四分之一。性能敏感,请谨慎对待new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)
我的应用在System.DateTime.GetDatePart中花费了12%的CPU时间。
评论
这是否与7年前最受好评并发布的答案相同?
– Alex
11月2日,11:51
#9 楼
易于阅读的方法是...//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...
评论
就性能而言,转换为字符串并进行解析是一个糟糕的主意。
–杰夫·普茨(Jeff Putz)
2015年9月10日下午12:31
@JeffPutz是的,但这很简单。适用于自动测试,在该测试中,从数据库插入和拉出的值丢失滴答声(我的确切情况)。但是,这个答案可能比实际要简单,因为var now = DateTime.Parse(DateTime.Now.ToString())可以正常工作。
–格林枪杀案
17年8月16日在9:32
@GrimmTheOpiner-大多数情况下,“ ...效果很好”,但不能保证。它的作用是:“将DateTime的值四舍五入为当前用户“控制面板”首选项中所配置的精度“ Long time”。通常,但不一定是秒。
–乔
18-09-6在20:07
就像它的简单一样,性能对于自动测试情况也不是问题。
– liang
19年8月21日在9:13
#10 楼
不是最快的解决方案,而是简单易懂:DateTime d = DateTime.Now;
d = d.Date.AddHours(d.Hour).AddMinutes(d.Minute).AddSeconds(d.Second)
#11 楼
关于Diadistis反应。这对我有用,除了在乘法之前必须使用Floor删除除法的小数部分。因此,d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
成为
d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
我期望两个Long值的除法结果a Long,因此删除了小数部分,但将其解析为Double,然后在乘法后留下了完全相同的值。
Eppsy
#12 楼
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);
#13 楼
这是我在此处发布的扩展方法版本,并且存在类似问题。这以一种易于阅读的方式验证了ticks值,并保留了原始DateTime实例的DateTimeKind。 (当存储到像MongoDB这样的数据库时,这具有微妙但相关的副作用。)如果我的真实目标是将DateTime截断为指定值(例如Hours / Minutes / Seconds / MS),则建议而是在您的代码中实现此扩展方法。它确保您只能截断到一个有效的精度,并且保留原始实例的重要DateTimeKind元数据: br />public static DateTime Truncate(this DateTime dateTime, long ticks)
{
bool isValid = ticks == TimeSpan.TicksPerDay
|| ticks == TimeSpan.TicksPerHour
|| ticks == TimeSpan.TicksPerMinute
|| ticks == TimeSpan.TicksPerSecond
|| ticks == TimeSpan.TicksPerMillisecond;
// https://stackoverflow.com/questions/21704604/have-datetime-now-return-to-the-nearest-second
return isValid
? DateTime.SpecifyKind(
new DateTime(
dateTime.Ticks - (dateTime.Ticks % ticks)
),
dateTime.Kind
)
: throw new ArgumentException("Invalid ticks value given. Only TimeSpan tick values are allowed.");
}
#14 楼
DateID.Text = DateTime.Today.ToShortDateString();
Use ToShortDateString() //Date 2-02-2016
Use ToShortDateString() // Time
并通过使用
ToLongDateString() // its show 19 February 2016.
:P
评论
-1。我可以看到问题可能被误解为要求生成字符串而不是DateTime,但这完全忽略了输出中的时间分量。 (这也使得不必访问Today属性。)
–培根
19-10-30在1:06
#15 楼
新方法String Date = DateTime.Today.ToString("dd-MMM-yyyy");
//定义字符串传递参数dd-mmm-yyyy返回2016年2月24日
或在文本框上显示
/>
txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");
//放在PageonLoad上
评论
-1。我可以看到问题可能被误解为要求生成字符串而不是DateTime,但这完全忽略了输出中的时间分量。 (这也使得不必访问Today属性。)
–培根
19-10-30在1:06
#16 楼
就我而言,我的目标是从datetimePicker工具中保存TimeSpan而不保存秒和毫秒,这是解决方案。 HH:mm”,然后将其转换回TimeSpan。var datetime = datetimepicker1.Value.ToString("HH:mm");
TimeSpan timeSpan = Convert.ToDateTime(datetime).TimeOfDay;
评论
更好的方法(意图更清晰,避免格式化为字符串并从字符串进行解析)是DateTime datetime = datetimepicker1.Value;。 TimeSpan timeSpan =新的TimeSpan(datetime.Hour,datetime.Minute,0);或者,您可以使用对TimeSpan值进行运算的Joe扩展方法的一种变体,并使用TimeSpan timeSpan = datetime.TimeOfDay.Truncate(TimeSpan.FromSeconds(1));缩短秒数。
–培根
19-10-30在1:26
#17 楼
我知道答案还很晚,但是摆脱毫秒的最佳方法是var currentDateTime = DateTime.Now.ToString("s");
尝试打印变量的值,它将显示日期时间,没有毫秒。
评论
这是不理想的。然后,您有一个字符串,而不是DateTime。
–杰夫·普茨(Jeff Putz)
19-10-10在14:19
评论
(第3次尝试...)由于20%的答案(1、2、3)描述了如何从DateTime的格式化字符串表示形式中删除或删除毫秒部分,因此可能需要进行编辑以明确指出“ truncate” /“ drop”毫秒表示“产生一个DateTime值,其中所有日期/时间分量都相同,但TimeOfDay.TotalMilliseconds为0。”人们当然不会阅读,只是为了消除任何歧义。