[C#] .NET DateTime에서 밀리 초를 자르는 방법

들어오는 요청의 타임 스탬프를 데이터베이스 저장된 값과 비교하려고합니다. 물론 SQL Server는 정시에 밀리 초의 정밀도를 유지하며 .NET DateTime으로 읽을 때 해당 밀리 초를 포함합니다. 그러나 시스템에 들어오는 요청은 그 정밀도를 제공하지 않으므로 간단히 밀리 초를 삭제해야합니다.

나는 명백한 것을 놓치고 있다고 생각하지만, 그것을 할 수있는 우아한 방법을 찾지 못했습니다 (C #).



답변

다음은 소수 밀리 초가있는 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
...


답변

var date = DateTime.Now;

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


답변

다음은 이전 답변을 기반으로 한 확장 방법으로 모든 해상도로자를 수 있습니다 …

용법:

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


답변

DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);


답변

때로는 연도 또는 월과 같은 캘린더 기반으로 잘라 내고 싶을 때가 있습니다. 다음은 해상도를 선택할 수있는 확장 방법입니다.

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


답변

밀리 초를 버리고 비교하는 대신 차이점을 비교하지 않는 이유는 무엇입니까?

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

또는

TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;


답변

덜 분명하지만 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);