2008-09-30 3 views
38

DateTime 객체를 특정 정밀도로 트림하는 가장 좋은 방법은 무엇입니까? 예를 들어 DateTime의 값이 '2008-09-29 09:41:43'인 경우에는 정밀도가 좋을뿐입니다. 이보다 더 좋은 방법은 없을까요?DateTime을 특정 정밀도로 트림하는 더 좋은 방법이 있습니까?

private static DateTime TrimDateToMinute(DateTime date) 
{ 
    return new DateTime(
     date.Year, 
     date.Month, 
     date.Day, 
     date.Hour, 
     date.Minute, 
     0); 
} 

내가 원하는 것은 변수를 두 번째, 분, 시간 또는 하루로 설정할 수 있도록하는 것입니다.

답변

71
static class Program 
{ 
    //using extension method: 
    static DateTime Trim(this DateTime date, long roundTicks) 
    { 
     return new DateTime(date.Ticks - date.Ticks % roundTicks, date.Kind); 
    } 

    //sample usage: 
    static void Main(string[] args) 
    { 
     Console.WriteLine(DateTime.Now); 
     Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerDay)); 
     Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerHour)); 
     Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerMillisecond)); 
     Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerMinute)); 
     Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerSecond)); 
     Console.ReadLine(); 
    } 

} 
+0

나는 이것을 매우 좋아한다. 3.5 프레임 워크를 사용했다면, 더 좋은 것이없는 한 내가 취할 수있는 길이다. 불행히도 2.0을 사용하고 있으므로 첫 번째 대답을 고수해야합니다. 감사! –

+8

범용 확장 메서드로 만들려면 DateTimeKind (지정되지 않음/Utc/Local)를 유지하는 것이 좋습니다. return new DateTime (date.Ticks - date.Ticks % roundTicks, date.Kind); – Joe

+0

... 또는 Kind 속성도 유지하는 한 줄 짜기 : d = d.AddTicks (- (d.Ticks + 30 * TimeSpan.TicksPerSecond) % TimeSpan.TicksPerMinute); – Joe

4

당신은 열거를

public enum DateTimePrecision 
{ 
    Hour, Minute, Second 
} 

public static DateTime TrimDate(DateTime date, DateTimePrecision precision) 
{ 
    switch (precision) 
    { 
    case DateTimePrecision.Hour: 
     return new DateTime(date.Year, date.Month, date.Day, date.Hour, 0, 0); 
    case DateTimePrecision.Minute: 
     return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, 0); 
    case DateTimePrecision.Second: 
     return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second); 
    default: 
     break; 
    } 
} 

를 사용하고 필요에 따라 확장 할 수있다.

+0

시간과 분에 대해 Minutes와 Seconds가 0을 사용할 때보다 반올림되어야하는지 궁금합니다. – Vivek

+0

꼭 필요한 경우 잘라내 기보다는 라운드로 코드를 적용 할 수 있습니다. 종종 절손이 시계가 작동하는 방식 인 것처럼 자연 스럽다고 느낍니다. – Rikalous

-4

당신은 시간을 time_t와 유사한 (연속) 숫자로 & 날짜가있는 경우, 당신은 단순히 등등 전체 분 (60 %), 시간,를 얻기 위해 모듈을 사용할 수 있습니다.

내 경험에 따르면 값은 실시간으로 정렬됩니다 (모듈로 60은 1 분에 발생 함). 그러나 이것이 어디에서나 보장 될 가능성은 거의 없습니다. 초 트림하는 코드 위

/* 
* Returns millisecond timing (in seconds) for the current time. 
* 
* Note: This function should be called once in single-threaded mode in Win32, 
*  to get it initialized. 
*/ 
double now_secs(void) { 

#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) 
    /* 
    * Windows FILETIME values are "100-nanosecond intervals since 
    * January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as 
    * the offset and it seems, so would they: 
    * 
    * <http://msdn.microsoft.com/en-us/library/ms724928(VS.85).aspx> 
    */ 
    SYSTEMTIME st; 
    FILETIME ft; 
    ULARGE_INTEGER uli; 
    static ULARGE_INTEGER uli_epoch; // Jan 1st 1970 0:0:0 

    if (uli_epoch.HighPart==0) { 
     st.wYear= 1970; 
     st.wMonth= 1; // Jan 
     st.wDay= 1; 
     st.wHour= st.wMinute= st.wSecond= st.wMilliseconds= 0; 
     // 
     st.wDayOfWeek= 0; // ignored 

     if (!SystemTimeToFileTime(&st, &ft)) 
      FAIL("SystemTimeToFileTime", GetLastError()); 

     uli_epoch.LowPart= ft.dwLowDateTime; 
     uli_epoch.HighPart= ft.dwHighDateTime; 
    } 

    GetSystemTime(&st); // current system date/time in UTC 
    if (!SystemTimeToFileTime(&st, &ft)) 
     FAIL("SystemTimeToFileTime", GetLastError()); 

    uli.LowPart= ft.dwLowDateTime; 
    uli.HighPart= ft.dwHighDateTime; 

    /* 'double' has less accuracy than 64-bit int, but if it were to degrade, 
    * it would do so gracefully. In practise, the integer accuracy is not 
    * of the 100ns class but just 1ms (Windows XP). 
    */ 
    return (double)(uli.QuadPart - uli_epoch.QuadPart)/10000000.0; 
#else 
    struct timeval tv; 
     // { 
     // time_t  tv_sec; /* seconds since Jan. 1, 1970 */ 
     // suseconds_t tv_usec; /* and microseconds */ 
     // }; 

    int rc= gettimeofday(&tv, NULL /*time zone not used any more (in Linux)*/); 
    assert(rc==0); 

    return ((double)tv.tv_sec) + ((tv.tv_usec)/1000)/1000.0; 
#endif 
} 
+3

멋진 C# 당신은 거기에 ... – leppie

0
static DateTime TrimDate(DateTime date, long roundTicks) 
    { 
     return new DateTime(date.Ticks - date.Ticks % roundTicks); 
    } 

    //sample usage: 
    static void Main(string[] args) 
    { 
     Console.WriteLine(DateTime.Now); 
     Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerDay)); 
     Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerHour)); 
     Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerMillisecond)); 
     Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerMinute)); 
     Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerSecond)); 
     Console.ReadLine(); 
    } 
+0

중복 답변을 제거하십시오. 나는 하나의 위대한 대답이 충분하다고 믿는다. – st78

-2
DateTime dt = new DateTime() 
dt = dt.AddSeconds(-dt.Second) 

: 여기

당신이 원하는 것을 얻을 수있는 코드 (하위 초 해상도)입니다.

+0

밀리 초를 트리밍하지 않고 나쁜'dt '가됩니다. – Denis

-1

나는이 방법을 좋아한다. 누군가는 날짜 종류 등을 보존하는 것이 좋다고 말했습니다. 이것은 새로운 날짜를 만들지 않기 때문에 나머지 틱을 뺍니다.

private DateTime FloorToHour(DateTime dt) 
{ 
    return dt.AddTicks(-1 * (dt.Ticks % TimeSpan.TicksPerHour)); 
} 
1

는 여기에 제시된 좋은 솔루션이 있습니다,하지만 난이 일을해야 할 때, 단순히 수행

DateTime truncDate; 
truncDate = date.Date; // trim to day 
truncDate = date.Date + TimeSpan.Parse(string.Format("{0:HH:00:00}", date)); // trim to hour 
truncDate = date.Date + TimeSpan.Parse(string.Format("{0:HH:mm}", date)); // trim to minute 
truncDate = date.Date + TimeSpan.Parse(string.Format("{0:HH:mm:ss}", date)); // trim to second 

는 도움이되기를 바랍니다.

+0

가 작동하지 않습니다. + 00:00:00 –

+0

@katz : 죄송합니다. 답장을 게시 할 때이 솔루션을 테스트했으며 방금 다시 테스트 했으므로 완벽하게 작동합니다. 위의 첫 번째 옵션 만 테스트하지 않으시겠습니까? 위의 모든 TimeSpan.Parse 메서드 호출이 00:00:00에 반환되는 것으로 나는 믿지 않습니다.위의 예에서 "truncDate"를 사용했기 때문에 변수 "date"자체 이외의 다른 변수를 사용하여이 연산의 결과를 수신 하시겠습니까? "날짜"변수 자체를 사용하는 경우, 위의 첫 번째 작업은 하루에 자르며 아래의 다른 결과를 손상시킵니다. –

+0

@katz : "truncDate"와 같은 DIFFERENT 변수를 사용하고 위의 모든 작업을 순서대로 수행하지 않은 다음 결과를 인쇄하십시오. 내 코드는 예제 일 뿐이지 만, 각 작업 (각 코드 라인)은 원하는 정밀도 (일,시, 분 또는 초)에 따라 별도로 사용해야합니다. 예를 들어, 마지막 줄만 실행 (초당 트림) 한 다음 결과를 인쇄하십시오. –

관련 문제