Reputation: 13
I'm trying to implement in C# the behavior of CTime::GetTime()
method.
Here there is a code snippet of my console application (written in C++/CLI):
int main(array<System::String ^> ^args)
{
int epochYear = 1970;
int epochMonth = 1;
int epochDay = 1;
DateTime managedEpochDate = DateTime(epochYear, epochMonth, epochDay);
int year = 2013;
int month = 2;
int day = 13;
int hour = 9;
int minutes = 49;
int seconds = 46;
// DateTime/CTime -> Numeric Time (__time64_t)
DateTime managedDateTime = DateTime(year, month, day, hour, minutes, seconds);
CTime nativeDateTime = CTime(year, month, day, hour, minutes, seconds);
DWORD nativeTimeToSerialize = nativeDateTime.GetTime();
UInt32 managedTimeToSerialize = (managedDateTime - managedEpochDate)
.TotalSeconds;
}
At the end I have the following different values:
Can anyone help me to understand the why of this difference?
Upvotes: 1
Views: 1002
Reputation: 35891
The difference comes from the fact that CTime
constructor you're using converts the time to UTC:
This constructor makes the appropriate conversion to UTC.
Whereas the DateTime
contructor (and the other one) is timezone unaware in this case:
The
Kind
property is initialized toDateTimeKind.Unspecified
.
The subtraction operator of DateTime
also doesn't take timezones into account:
The
Subtraction(DateTime, DateTime)
method does not consider the value of theKind
property of the twoDateTime
values when performing the subtraction.
To get the desired result set the last parameter for the CTime
constructor appropriately, e.g.:
CTime nativeDateTime = CTime(year, month, day, hour, minutes, seconds, 0);
For modifying DateTime
usages instead you need to have:
int epochYear = 1970;
int epochMonth = 1;
int epochDay = 1;
DateTime managedEpochDateUtc
= new DateTime(epochYear, epochMonth, epochDay, 0, 0, 0, DateTimeKind.Utc);
int year = 2013;
int month = 2;
int day = 13;
int hour = 9;
int minutes = 49;
int seconds = 46;
DateTime managedDateTimeLocal
= new DateTime(year, month, day, hour, minutes, seconds, DateTimeKind.Local);
DateTime managedDateTimeUtc = managedDateTimeLocal.ToUniversalTime();
uint managedTimeToSerialize = (uint)(managedDateTimeUtc - managedEpochDateUtc)
.TotalSeconds;
Or, as suggested by Mgetz you can use DateTimeOffset
instead of DateTime
, which is generally recommended because DateTime
doesn't handle timezones very clearly.
Upvotes: 1