我有一个“要求”给出最接近的第二个时间戳...但不是更准确。舍入或截断时间很好。
我想出了这种可憎的行为
dateTime = DateTime.Parse(DateTime.UtcNow.ToString("U"));
(U是长格式日期和时间。“2007年1月3日17:25:30”)
是否有一些不那么可怕的方法来实现这个目标?
编辑:所以从链接截断毫秒回答(感谢约翰奥多姆)我将要做到这一点
private static DateTime GetCurrentDateTimeNoMilliseconds()
{
var currentTime = DateTime.UtcNow;
return new DateTime(currentTime.Ticks - (currentTime.Ticks % TimeSpan.TicksPerSecond), currentTime.Kind);
}
几乎不那么可怕..但它确实保留了我所关心的日期时间'种类'。我的解决方案没有。
答案 0 :(得分:33)
您可以将此实现为一种扩展方法,允许您使用基础Ticks将给定的DateTime修剪为指定的精度:
public static DateTime Trim(this DateTime date, long ticks) {
return new DateTime(date.Ticks - (date.Ticks % ticks), date.Kind);
}
然后很容易将日期修剪成各种准确度:
DateTime now = DateTime.Now;
DateTime nowTrimmedToSeconds = now.Trim(TimeSpan.TicksPerSecond);
DateTime nowTrimmedToMinutes = now.Trim(TimeSpan.TicksPerMinute);
答案 1 :(得分:5)
您可以使用this构造函数:
public DateTime(
int year,
int month,
int day,
int hour,
int minute,
int second
)
所以它会是:
DateTime dt = DateTime.Now;
DateTime secondsDt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
答案 2 :(得分:2)
如果你真的希望围绕时间到最近的秒,你可以使用:
DateTime.MinValue
.AddSeconds(Math.Round((DateTime.Now - DateTime.MinValue).TotalSeconds));
然而,除非额外的半秒确实有所不同,否则你可以删除毫秒部分:
DateTime.Now.AddTicks( -1 * (DateTime.Now.Ticks % TimeSpan.TicksPerSecond));
答案 3 :(得分:1)
试试这个
TimeSpan span= dateTime.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;
答案 4 :(得分:1)
使用选定的解决方案后,我对它的运作感到满意。但是,此处发布的扩展方法的实现未提供任何验证,以确保您传入的ticks值是有效的ticks值。它们也不会保留被截断的DateTime对象的DateTimeKind。 (当存储到像MongoDB这样的数据库时,这具有微妙但相关的副作用。)
如果真正的目标是将DateTime截断为指定的值(例如Hours / Minutes / Seconds / MS),则建议您在代码中实现此扩展方法。它确保您只能截断到有效的精度,并且保留原始实例的重要DateTimeKind元数据:
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.");
}
然后您可以使用如下方法:
DateTime dateTime = DateTime.UtcNow.Truncate(TimeSpan.TicksPerMillisecond);
dateTime.Kind => DateTimeKind.Utc
答案 5 :(得分:0)
这里是一种舍入方法,可以舍入或舍入到最接近的秒数,而不仅仅是修整:
public static DateTime Round(this DateTime date, long ticks = TimeSpan.TicksPerSecond) {
if (ticks>1)
{
var frac = date.Ticks % ticks;
if (frac != 0)
{
// Rounding is needed..
if (frac*2 >= ticks)
{
// round up
return new DateTime(date.Ticks + ticks - frac);
}
else
{
// round down
return new DateTime(date.Ticks - frac);
}
}
}
return date;
}
可以这样使用:
DateTime now = DateTime.Now;
DateTime nowTrimmedToSeconds = now.Round(TimeSpan.TicksPerSecond);
DateTime nowTrimmedToMinutes = now.Round(TimeSpan.TicksPerMinute);