簡體   English   中英

讓 datetime.now 返回到最近的秒

[英]Have datetime.now return to the nearest second

我有一個“要求”為最近的秒提供時間戳......但不會比這更准確。 四舍五入或截斷時間都可以。

我想出了這個可憎的東西

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

幾乎沒有那么可怕......但它確實保留了我關心的“那種”約會時間。 我的解決方案沒有。

您可以將其實現為一個擴展方法,該方法允許您使用基礎 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);

您可以使用構造函數:

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

如果你真的想把時間四舍五入到最接近的秒,你可以使用:

DateTime.MinValue
        .AddSeconds(Math.Round((DateTime.Now - DateTime.MinValue).TotalSeconds));

但是,除非額外的半秒真的有所作為,否則您可以刪除毫秒部分:

DateTime.Now.AddTicks( -1 * (DateTime.Now.Ticks % TimeSpan.TicksPerSecond));

嘗試這個

TimeSpan span= dateTime.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;

使用選定的解決方案后,我很滿意它運行良好。 但是,此處發布的擴展方法的實現不提供任何驗證以確保您傳入的刻度值是有效的刻度值。 它們也不保留被截斷的 DateTime 對象的 DateTimeKind。 (當存儲到像 MongoDB 這樣的數據庫時,這會產生微妙但相關的副作用。)

如果真正的目標是將 DateTime 截斷為指定值(即小時/分鍾/秒/毫秒),我建議改為在您的代碼中實現此擴展方法。 它確保您只能截斷到有效精度,並保留原始實例的重要 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

這是一種向上或向下舍入到最接近的秒而不只是修剪的舍入方法:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM