According to my understanding time_t rawtime = 0xffFFffFF
is GMT: Sunday, February 7, 2106 6:28:15 AM
But programm below brings Thu 1970-01-01 02:59:59 MSK
in some compilers and just crashes in others.
int main()
{
time_t rawtime = 0xffFFffFF;
struct tm ts;
char buf[80];
ts = *localtime(&rawtime);
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
printf("%s\n", buf);
return 0;
}
Error behaviors appears when rawtime >0x7fFFffFF
. Why? How to solve this?
UPD: I need to have array of alarms and proceed action when time comes. This is embedded system and I can't waist memory and resources for complicated data types.
On most platforms type time_t
is a signed integer. Also on most platforms time_t
counts time from January 1, 1970. Combining those two facts, we have negative time_t
values corresponding to dates before January 1, 1970.
If time_t
on your machine is a signed 32-bit integer, 0xffffffff
is -1. Theoretically, therefore, this value corresponds to 23:59:59 UTC on December 31, 1969 — that is, one second before UTC midnight. But in some contexts, -1 indicates an error. So although I've never encountered it, I'm not completely surprised if there's a localtime()
implementation out there that treats a value of -1 on input as an error.
You said it "crashed", but that's partly your fault. localtime
indicates failure by returning a null pointer. So it's safer to write
struct tm *ts;
ts = localtime(&rawtime);
if(ts == NULL) {
fprintf(stderr, "localtime failed\n");
exit(1);
}
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
If time_t
is a signed, 32-bit value, its maximum value is 2147483647 which (still assuming the Unix epoch of 1970) corresponds to January 19, 2038 at 03:14:07 UTC. The minimum value, 2147483648, corresponds to December 13, 1901 at 20:45:52 UTC.
You're right, if time_t
were treated as unsigned, the maximum 32-bit value would be 4294967295 and would correspond to the date and time in 2106 you mentioned.
If time_t
is a 64-bit type, as is increasingly popular (and more or less necessary in order to forestall the y2.038k problem), the maximum value is so big that it's practically meaningless. (It's so big that the year can't even be represented in 32 bits.)
Finally, it's worth remembering that the interpretation of time_t
is platform-specific. Theoretically, it doesn't necessarily count seconds, it doesn't necessarily count from January 1, 1970, and it's not even necessarily an integer. Even where those facts do hold, there's no rule that says time_t
necessarily has to be signed, so in a program designed for widespread portability I wouldn't count on there being values corresponding to 1901–1970, since on some platforms they might correspond to 2038–2106, after all.
The type and range of time_t
are implementation-defined and there are no minimum requirements. It could be signed, unsigned, 32-bit, 64-bit, floating point, etc.
If the compiler you're using doesn't have a time_t
whose range meets your requirements, you could:
time_t
, ortime_t
on your compiler.As mentioned in comments, the "crash" is likely due to localtime
returning a null pointer due to the out of range input, and you dereference it without first checking for null.
User contributions licensed under CC BY-SA 3.0