본문 바로가기

Programing/닷넷

[C#] DateTime.Now 분석

닷넷에는 시스템의 시간을 가져오는 방법은 DateTime.Now을 쓰면 간단하다.

그런데 반대로 시스템의 시간을 설정하는 방법은 사람들은 잘 모르는 것 같다.


StackOverflow 같은데 보면 Win32 함수를 마샬링해서 쓰는 방법뿐이다.

심지어 MSDN도 마찬가지이다. How to: Get or Set the System Time  GetSystemTime 와 SetSystemTime 함수를 Invoke해서 구현을 해놓았다.


MSDN에도 그러하니 DateTime.Now는 내부적으로 GetsystemTime을 호출해서 DateTime 객체로 돌려주는 거겠지 생각을 했는데 틀렸다.


우선 Now는 아래와 같은 프로퍼티이다.

public static DateTime Now

{

    get

    {

        return UtcNow.ToLocalTime();

    } 

}


UtcNow역시 프로퍼티인데 컴퓨터의 현재 날짜와 시간을 UTC시간으로 가져오는 역할을 한다.이 프로퍼티는 아래와 같이 구현되어 있다.

public static DateTime UtcNow

{

    get

    {

        return new DateTime((ulong) ((GetSystemTimeAsFileTime() + 0x701ce1722770000L) | 0x4000000000000000L));

    }

}


GetSystemTimeAsFileTime 메소드를 호출했는데 이것은 Win32 함수랑 이름이 동일하다.

void WINAPI GetSystemTimeAsFileTime(

  _Out_  LPFILETIME lpSystemTimeAsFileTime

);


LPFILETIME는 FILETIME 구조체를 가리키는 포인터인데 아래와 같다.

typedef struct _FILETIME {

  DWORD dwLowDateTime;

  DWORD dwHighDateTime;

} FILETIME, *LPFILETIME;

DWORD는 unsigned int이므로 사실 32+32 = 64비트이다.

C#에서 ulong 타입은 UInt64의 별칭이므로 FILETIME은 64비트로 대응할 수 있는 것이다.