I have struct tm
that represents time 1900-01-01 00:00:00
. How can I add offset in hours to it? For example, I have offset in hours - value 1048621
(aprox. 119.7 years).
Assuming the resulting date/time falls into the range representable by time_t
, you can add the hours offset to tm::tm_hour
then call mktime
to normalize.
#include <time.h>
#include <stdio.h>
int main()
{
struct tm t = { 0 };
t.tm_mday = 1; // Jan 1st 1900
t.tm_hour = 1048621;
if(mktime(&t) == -1) return 1;
printf("%d-%02d-%02d %02d:%02d:%02d\n",
t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec);
return 0;
}
Output :
2019-08-17 13:00:00
[ EDIT ] As pointed out in a comment, the above mktime
call fails with MSVC. Turns out that Microsoft's mktime
implementation does a precheck on the tm
argument, and unconditionally fails if tm_year < 69
before/without even looking at the other tm
fields. While it is expected for mktime
to fail if the end date/time falls outside the time_t
range, in particular if it is earlier than the start of the epoch (usually Jan 1st 1970), such check should normally be done after (re)normalization.
Below is updated code that adds range validation, and was verified to work with gcc and msvc .
#include <time.h>
#include <limits.h>
#include <stdio.h>
int main()
{
const int tmYear1970 = 70;
const int tmDay1970 = tmYear1970 * 365 + tmYear1970 / 4; // 25568
const int tmHour1970 = tmDay1970 * 24; // 613632
const int tmHourMax = INT_MAX - tmHour1970; // 2146870015
int tmHour = 1048621;
if(tmHour < tmHour1970 || tmHour > tmHourMax) return 2;
struct tm t = { 0 };
t.tm_mday = 1; // Jan 1st 1900 12 AM
t.tm_year = tmYear1970;
t.tm_hour = tmHour - tmHour1970;
t.tm_isdst = -1;
if (mktime(&t) == -1) return 1;
printf("%d-%02d-%02d %02d:%02d:%02d\n",
t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
t.tm_hour, t.tm_min, t.tm_sec);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.