Have datetime.now return to the nearest second

前端 未结 6 723
眼角桃花
眼角桃花 2021-01-04 04:38

I have a \"requirement\" to give a timestamp to the nearest second... but NOT more accurate than that. Rounding or truncating the time is fine.

I have come up with t

相关标签:
6条回答
  • 2021-01-04 04:49

    If you really want to round the time to the nearest second, you can use:

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

    However unless that extra half a second really makes a difference, you can just remove the millisecond portion:

    DateTime.Now.AddTicks( -1 * (DateTime.Now.Ticks % TimeSpan.TicksPerSecond));
    
    0 讨论(0)
  • 2021-01-04 04:52

    You can use this constructor:

    public DateTime(
        int year,
        int month,
        int day,
        int hour,
        int minute,
        int second
    )
    

    so it would be:

    DateTime dt = DateTime.Now;
    DateTime secondsDt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
    
    0 讨论(0)
  • 2021-01-04 05:05

    Try this

    TimeSpan span= dateTime.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
    return span.TotalSeconds;
    
    0 讨论(0)
  • 2021-01-04 05:06

    Here is a rounding method that rounds up or down to the nearest second instead of just trimming:

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

    It can be used like this:

    DateTime now = DateTime.Now;
    DateTime nowTrimmedToSeconds = now.Round(TimeSpan.TicksPerSecond);
    DateTime nowTrimmedToMinutes = now.Round(TimeSpan.TicksPerMinute);
    
    0 讨论(0)
  • 2021-01-04 05:08

    You could implement this as an extension method that allows you to trim a given DateTime to a specified accuracy using the underlying Ticks:

    public static DateTime Trim(this DateTime date, long ticks) {
       return new DateTime(date.Ticks - (date.Ticks % ticks), date.Kind);
    }
    

    Then it is easy to trim your date to all kinds of accuracies like so:

    DateTime now = DateTime.Now;
    DateTime nowTrimmedToSeconds = now.Trim(TimeSpan.TicksPerSecond);
    DateTime nowTrimmedToMinutes = now.Trim(TimeSpan.TicksPerMinute);
    
    0 讨论(0)
  • 2021-01-04 05:09

    After working with the selected solution I am satisfied that it works well. However the implementations of the extension methods posted here do not offer any validation to ensure the ticks value you pass in is a valid ticks value. They also do not preserve the DateTimeKind of the DateTime object being truncated. (This has subtle but relevant side effects when storing to a database like MongoDB.)

    If the true goal is to truncate a DateTime to a specified value (i.e. Hours/Minutes/Seconds/MS) I recommend implementing this extension method in your code instead. It ensures that you can only truncate to a valid precision and it preserves the important DateTimeKind metadata of your original instance:

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

    Then you can use the method like this:

    DateTime dateTime = DateTime.UtcNow.Truncate(TimeSpan.TicksPerMillisecond);
    
    dateTime.Kind => DateTimeKind.Utc
    
    0 讨论(0)
提交回复
热议问题