Как обрезать миллисекунды от .NET DateTime - PullRequest
300 голосов
/ 17 июня 2009

Я пытаюсь сравнить метку времени из входящего запроса с сохраненным значением базы данных. Конечно, SQL Server сохраняет некоторую точность времени в миллисекундах, а при чтении в .NET DateTime он включает эти миллисекунды. Однако входящий запрос к системе не обеспечивает такой точности, поэтому мне нужно просто отбросить миллисекунды.

Мне кажется, что я упускаю что-то очевидное, но я не нашел элегантного способа сделать это (C #).

Ответы [ 13 ]

510 голосов
/ 17 июня 2009

Следующее будет работать для DateTime, который имеет дробные миллисекунды, а также сохраняет свойство Kind (Local, Utc или Undefined).

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
    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
...
134 голосов
/ 17 июня 2009
var date = DateTime.Now;

date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
48 голосов
/ 21 апреля 2010

Вот метод расширения, основанный на предыдущем ответе, который позволит вам усечь любое разрешение ...

Использование:

DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond);
DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)

Класс:

public static class DateTimeUtils
{
    /// <summary>
    /// <para>Truncates a DateTime to a specified resolution.</para>
    /// <para>A convenient source for resolution is TimeSpan.TicksPerXXXX constants.</para>
    /// </summary>
    /// <param name="date">The DateTime object to truncate</param>
    /// <param name="resolution">e.g. to round to nearest second, TimeSpan.TicksPerSecond</param>
    /// <returns>Truncated DateTime</returns>
    public static DateTime Truncate(this DateTime date, long resolution)
    {
        return new DateTime(date.Ticks - (date.Ticks % resolution), date.Kind);
    }
}
27 голосов
/ 17 июня 2009
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
9 голосов
/ 17 июня 2009

Вместо того чтобы отбрасывать миллисекунды, а затем сравнивать, почему бы не сравнить разницу?

DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;

или

TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
8 голосов
/ 02 марта 2014

Иногда вы хотите усечь что-то на основе календаря, например, год или месяц. Вот метод расширения, который позволяет вам выбрать любое разрешение.

public enum DateTimeResolution
{
    Year, Month, Day, Hour, Minute, Second, Millisecond, Tick
}

public static DateTime Truncate(this DateTime self, DateTimeResolution resolution = DateTimeResolution.Second)
{
    switch (resolution)
    {
        case DateTimeResolution.Year:
            return new DateTime(self.Year, 1, 1, 0, 0, 0, 0, self.Kind);
        case DateTimeResolution.Month:
            return new DateTime(self.Year, self.Month, 1, 0, 0, 0, self.Kind);
        case DateTimeResolution.Day:
            return new DateTime(self.Year, self.Month, self.Day, 0, 0, 0, self.Kind);
        case DateTimeResolution.Hour:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerHour));
        case DateTimeResolution.Minute:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMinute));
        case DateTimeResolution.Second:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerSecond));
        case DateTimeResolution.Millisecond:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMillisecond));
        case DateTimeResolution.Tick:
            return self.AddTicks(0);
        default:
            throw new ArgumentException("unrecognized resolution", "resolution");
    }
}
8 голосов
/ 17 июня 2009

Менее очевидно, но более чем в 2 раза быстрее:

// 10000000 runs

DateTime d = DateTime.Now;

// 484,375ms
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);

// 1296,875ms
d = d.AddMilliseconds(-d.Millisecond);
2 голосов
/ 10 сентября 2015

Простой ...

//Remove milliseconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);

И еще ...

//Remove seconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm"), "yyyy-MM-dd HH:mm", null);

//Remove minutes
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH"), "yyyy-MM-dd HH", null);

//and go on...
1 голос
/ 25 октября 2016

Округлить до второго:

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

Заменить на TicksPerMinute, чтобы округлить до минуты.


Если ваш код чувствителен к производительности, будьте осторожны с

new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)

Мое приложение тратило 12% процессорного времени в System.DateTime.GetDatePart .

1 голос
/ 24 февраля 2016

Новый метод

String Date = DateTime.Today.ToString("dd-MMM-yyyy"); 

// определить параметр передачи строки dd-ммм-гггг возвращение 24 февраля 2016

или отображается в текстовом поле

txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");

// положить на PageonLoad

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...