I'm converting some c++ to c# code. I cannot reproduce equivalent values when converting from the tm struct and mktime() to c#.
Example: Both versions use the same values:
int year = 2022;
int month = 9;
int day = 5;
int hour = 0;
int minute = 27;
int second = 20;
In C++:
struct tm sampleTime;
unsigned long longTime;
sampleTime.tm_year = year;
sampleTime.tm_mon = month - 1;
sampleTime.tm_mday = day;
sampleTime.tm_hour = hour;
sampleTime.tm_min = minute;
sampleTime.tm_sec = second;
sampleTime.tm_wday = 0;
sampleTime.tm_yday = 0;
sampleTime.tm_isdst= 0;
longTime = mktime(&thistime);
The value of longTime is 1662366439.
In C#:
DateTime sampleTime = new DateTime(year, month, day, hour, minute, second);
DateTime unixEpoch = new DateTime(1970, 1, 1);
ulong longTime = (ulong)(sampleTime - unixEpoch).TotalSeconds;
The value of longTime is 1662337639.
So they are very close but off, and I need them to be equivalent. What am I missing here?
mktime()takes in atmexpressed in local time, whereas the Unix epoch is expressed in UTC time instead.The C#
DateTime()constructors you are calling don't know whether the specified date/time values are in local time or UTC time, so theKindproperty of the resultingDateTimes isUnspecified, which can cause calculation errors. So, you need to use otherDateTimeconstructors that make eachKindexplicit so adjustments can be made as needed during calculations, eg:That being said, note that the C++ code is setting
sampleTime.tm_isdst = 0to indicate that the specified date/time IS NOT in DST time, even if the real date/time actually IS in DST time.I'm not sure how to handle that on the C# side. You will probably have to lookup whether the specified
sampleTimeis actually in DST (ie, viaTimeZoneInfo.Local.IsDaylightSavingTime()) and if so then adjust it accordingly to move it out of DST before then performing further calculations on it, eg: