Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
8 years, 5 months ago.
mktime bug for year 2038?
similiar to this question https://developer.mbed.org/questions/68608/Year-2038-Bug-rtc_timeh-and-timeh-32bit-/ i have another problem for which i think mktime is behaving wrong. mktime generates a date with year 1902 when the struct tm has year 2038.
Serial pc(SERIAL_TX, SERIAL_RX); const char* TIME_PATTERN = "%d-%m-%Y"; std::string getTimeAsString(tm * seconds, std::string pattern) { char buf[40]; strftime(buf, 40, pattern.c_str(), seconds); std::string time = buf; return time; } std::string getTimeAsString(time_t seconds, std::string pattern) { char buf[40]; strftime(buf, 40, pattern.c_str(), localtime(&seconds)); std::string time = buf; return time; } time_t getTimeAsObject(std::string timeString, std::string patternOfTimeString) { struct tm time_buffer; time_buffer.tm_year = (uint8_t)100; time_buffer.tm_mon = (uint8_t)0; time_buffer.tm_mday = (uint8_t)1; time_buffer.tm_hour = (uint8_t)1; time_buffer.tm_min = (uint8_t)0; time_buffer.tm_sec = (uint8_t)0; strptime(timeString.c_str(), patternOfTimeString.c_str(), &time_buffer); pc.printf("Here is always correct --> %s\n", getTimeAsString(&time_buffer, TIME_PATTERN).c_str()); time_t desired_time = mktime(&time_buffer); //<------I THINK THIS LINE IS BEHAVING WRONG return desired_time; } int main() { pc.baud(9600); time_t dateTime1 = getTimeAsObject("31-12-2037", TIME_PATTERN); std::string time = getTimeAsString(dateTime1, TIME_PATTERN); pc.printf("Correct : %s\n", time.c_str()); dateTime1 = getTimeAsObject("31-12-2038", TIME_PATTERN); time = getTimeAsString(dateTime1, TIME_PATTERN); pc.printf("----Wrong-----: %s\n", time.c_str()); }
the output of the program is
Here is always correct --> 31-12-2037 Correct : 31-12-2037 Here is always correct --> 31-12-2038 ----Wrong-----: 24-11-1902
So is this a bug or how can i generate the right date as string?
2 Answers
8 years, 5 months ago.
If you calculate with a signed integer starting from 1970 it overflows in 2038, so there you have your problem.
It even has its own wiki page: https://en.wikipedia.org/wiki/Year_2038_problem
So kinda working as intended, although eventually they probably are going to need to switch to either 64-bit or unsigned integers.
Hi Erik, thanks for your answer. So it means that for the moment there is no way how to go around this problem with mktime on mbed? I am making use of difftime(time_t, time_t) to compare time instances thats why i used mktime. Is there another way to do time comparison except manually comparing struct tm member variables one by one?
posted by 02 Jun 20168 years, 5 months ago.
Hello,
When I tried to compile the code I have got
Error: Identifier "strptime" is undefined in "main.cpp", Line: 33, Col: 6
So I was not able to fully test your code. Anyway, maybe this helps you find the bug:
After commenting out the strptime
function and setting the time_buffer
to 2038-12-31 manually:
time_t getTimeAsObject(std::string timeString, std::string patternOfTimeString) { struct tm time_buffer; time_buffer.tm_year = (uint8_t)(2038 - 1900); time_buffer.tm_mon = (uint8_t)(12 - 1); time_buffer.tm_mday = (uint8_t)31; time_buffer.tm_hour = (uint8_t)1; time_buffer.tm_min = (uint8_t)0; time_buffer.tm_sec = (uint8_t)0; // strptime(timeString.c_str(), patternOfTimeString.c_str(), &time_buffer); pc.printf("Here is always correct --> %s\n", getTimeAsString(&time_buffer, TIME_PATTERN).c_str()); time_t desired_time = mktime(&time_buffer); //<------I THINK THIS LINE IS BEHAVING WRONG return desired_time; } int main() { pc.baud(9600); time_t dateTime1 = getTimeAsObject("31-12-2037", TIME_PATTERN); std::string time = getTimeAsString(dateTime1, TIME_PATTERN); pc.printf("Correct : %s\n", time.c_str()); dateTime1 = getTimeAsObject("31-12-2038", TIME_PATTERN); time = getTimeAsString(dateTime1, TIME_PATTERN); pc.printf("----Wrong-----: %s\n", time.c_str()); }
I have got a correct printout:
Here is always correct --> 31-12-2038 Correct : 31-12-2038 Here is always correct --> 31-12-2038 ----Wrong-----: 31-12-2038
So it seems that the mktime
function works correctly.
Hi Zoltan, thanks for your answer. That is strange since your change is causing following output in my board
Here is always correct --> 31-12-2038 Correct : 24-11-1902 Here is always correct --> 31-12-2038 ----Wrong-----: 24-11-1902
Are you testing on any mbed board?. I have a NucleoF401 and strptime is part of time.h. I think what Erik wrote is the answer to my problem that as it seams can not be solved.
posted by 02 Jun 2016