Santhosh
Santhosh

Reputation: 6707

Converting SYSTEMTIME (Native C++) to DateTime (C#)

I have a C++ client talking to a C# server and I have custom serialization for user defined types.

Now I need to pass a date and time structure from C++ to C#. Googling led to the following approach:

  1. Fill up the date/time in SYSTEMTIME structure (This is not the current system time. But rather it will be filled up by the program based on certain conditions)
  2. Convert SYSTEMTIME to FILETIME
  3. Convert FILETIME to __int64 (this gives a 64 bit value representing the number of 100 nanoseconds interval from Jan 1, 1601)
  4. Use this 64 bit value in the constructor to DateTime in C#.

Just to test the waters, I wrote 2 snippets one in (native)C++ that does steps 1,2,3 and the other in C# that does Step4. No automatic invocation from C++ to C# yet.

I manually pulled out the value from step 3 (130220830133980000L) and used it in C# and here is code snippet and the output I get.

C++ Code

SYSTEMTIME st;

GetSystemTime(&st);

printf("\n In C++ : %04d:%02d:%02d:%02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

FILETIME fileTime;
if(!SystemTimeToFileTime(&st, &fileTime)) {
    wcout << "Conversion from system time to file time failed. Error : " << GetLastError();
}

__int64 ticks = (((ULONGLONG) fileTime.dwHighDateTime) << 32) + fileTime.dwLowDateTime;

C# Code

DateTime dob = new DateTime(130220830133980000L, DateTimeKind.Utc);
Console.WriteLine("In C# : " + dob.Year + ":" + dob.Month + ":" + dob.Day + ":" + dob.Hour + ":" + dob.Minute + ":" + dob.Second + ":" + dob.Millisecond);

The output:

In C++ : 2013:08:27:13:16:53:398

In C# : 413:8:27:13:16:53:398

All the values except the year part can be retrieved correctly. The year 2013 in C++ becomes 413 in C#. I can't figure out why the year part changes.

Am I doing the conversion correctly? If there is any alternate approach to pass date and time information from C++ to C# and vice versa?

Upvotes: 5

Views: 8032

Answers (1)

David Heffernan
David Heffernan

Reputation: 612914

The value you pass to the DateTime constructor is a FILETIME, that is the number of 100 nanoseconds interval from Jan 1, 1601. The value that the DateTime constructor expects is the number of 100-nanosecond intervals that have elapsed since January 1, 0001. Hence the 1600 year discrepancy. You can solve your problems by simply applying a 1600 year offset.

Upvotes: 6

Related Questions