HiveBrain v1.2.0
Get Started
← Back to all entries
snippetcsharpCritical

How to truncate milliseconds off of a .NET DateTime

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
nettruncatehowdatetimemillisecondsoff

Problem

I'm trying to compare a time stamp from an incoming request to a database stored value. SQL Server of course keeps some precision of milliseconds on the time, and when read into a .NET DateTime, it includes those milliseconds. The incoming request to the system, however, does not offer that precision, so I need to simply drop the milliseconds.

I feel like I'm missing something obvious, but I haven't found an elegant way to do it (C#).

Solution

The following will work for a DateTime that has fractional milliseconds, and also preserves the Kind property (Local, Utc or Undefined).

DateTime dateTime = ... anything ...
dateTime = new DateTime(
    dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond), 
    dateTime.Kind
    );


or the equivalent and shorter:

dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));


This could be generalized into an extension method:

public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
    if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException

    // Some comments suggest removing the following line.  I think the check
    // for MaxValue makes sense - it's often used to represent an indefinite expiry date.
    // (The check for DateTime.MinValue has no effect, because DateTime.MinValue % timeSpan
    // is equal to DateTime.MinValue for any non-zero value of timeSpan.  But I think
    // leaving the check in place makes the intent clearer).
    // YMMV and the fact that different people have different expectations is probably
    // part of the reason such a method doesn't exist in the Framework.
    if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) return dateTime; // do not modify "guard" values

    return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}


which is used as follows:

dateTime = dateTime.Truncate(TimeSpan.FromMilliseconds(1)); // Truncate to whole ms
dateTime = dateTime.Truncate(TimeSpan.FromSeconds(1)); // Truncate to whole second
dateTime = dateTime.Truncate(TimeSpan.FromMinutes(1)); // Truncate to whole minute
...

Code Snippets

DateTime dateTime = ... anything ...
dateTime = new DateTime(
    dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond), 
    dateTime.Kind
    );
dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));
public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
    if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException

    // Some comments suggest removing the following line.  I think the check
    // for MaxValue makes sense - it's often used to represent an indefinite expiry date.
    // (The check for DateTime.MinValue has no effect, because DateTime.MinValue % timeSpan
    // is equal to DateTime.MinValue for any non-zero value of timeSpan.  But I think
    // leaving the check in place makes the intent clearer).
    // YMMV and the fact that different people have different expectations is probably
    // part of the reason such a method doesn't exist in the Framework.
    if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) return dateTime; // do not modify "guard" values

    return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}
dateTime = dateTime.Truncate(TimeSpan.FromMilliseconds(1)); // Truncate to whole ms
dateTime = dateTime.Truncate(TimeSpan.FromSeconds(1)); // Truncate to whole second
dateTime = dateTime.Truncate(TimeSpan.FromMinutes(1)); // Truncate to whole minute
...

Context

Stack Overflow Q#1004698, score: 702

Revisions (0)

No revisions yet.