Convert date / time (like Double) to struct * tm in C ++

I get the date / time as a double value from C # (DateTime.ToOADate (), which is OLE Date Time). It contains past days from 1899/12/31, while part is a passing part of the day. Multiplying from 86400, I get seconds and from this, finally, in the daytime.

Getting the date, however, is more difficult. I still do not have a solution, except for the terms for which UNIX time extends (1970/01/01 - 2038/01/19). During this time, mktime () can be used to convert past days to date and time.

double OleDateTimeValue = 28170.654351851852; // 14.02.1977 15:42:16
struct tm * timeinfo;
int passedDays = (int)OLEDateTimeValue;

// between 1.1.1970 and 18.1.2038
if((passedDays >= 25569) && (passedDays <= 50423)) 
{
    timeinfo->tm_year = 70; //1970
    timeinfo->tm_mon = 0;
    timeinfo->tm_mday = 1 + (passedDays - 25569);
    mktime(timeinfo);
}    
else // date outside the UNIX date/time
{
}

Now mktime () formats the tm structure so that it represents the requested date, or returns -1 if the value is outside the dates.

? , MFC Visual ++ 6.0.

,

+3
3
+3

- ​​ !

, 1900-03-01 2100-02-28. , , , 1900 2100 . Microsoft COleDateTime .

int leapDays = (int)((OleDateTimeValue + 1400) / 1461);
timeinfo->tm_year = (int)((OleDateTimeValue - leapDays - 1) / 365);
int janFirst = timeinfo->tm_year * 365 + (int)((timeinfo->tm_year + 7) / 4);
int wholeDays = (int)OleDateTimeValue - janFirst;
if (timeinfo->tm_year % 4 != 0 && wholeDays > 58)
    ++wholeDays;
static int firstOfMonth[12] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
timeinfo->tm_mon = std::upper_bound(&firstOfMonth[0], &firstOfMonth[12], wholeDays) - &firstOfMonth[0];
timeinfo->tm_mday = wholeDays - firstOfMonth[timeinfo->tm_mon - 1] + 1;

, .

+2

Converting to time_t should be simple (multiply by 86400 and add a constant offset), then you can use the function localtime. But you will still be limited by the UNIX time range. If you really need to go beyond this range, then villintehaspam's answer, as well as copying all the individual fields, looks like a way to go.

0
source

Source: https://habr.com/ru/post/1783262/


All Articles