让datetime.now返回到最近的秒

时间:2014-02-11 14:28:54

标签: c# c#-4.0 datetime

我有一个“要求”给出最接近的第二个时间戳...但不是更准确。舍入或截断时间很好。

我想出了这种可憎的行为

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

几乎不那么可怕..但它确实保留了我所关心的日期时间'种类'。我的解决方案没有。

6 个答案:

答案 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);