Reputation: 1141
#include <stdio.h>
#include <time.h>
int main(int argc, char* argv[])
{
struct tm stm;
stm.tm_sec = 27;
stm.tm_min = 5;
stm.tm_hour = 18;
stm.tm_mday = 2;
stm.tm_mon = 0;
stm.tm_year = 43;
stm.tm_wday = 0;
stm.tm_yday = 0;
printf("%d\n", mktime(&stm));
getchar();
return 0;
}
prints -1
What am I misunderstanding?
[+edit] this is using Visual Studio 2012 with 32 bit target. I guess a follow up question would be 'what is the recommended method for storing arbitrary date/time values (i.e. those which may be before 1900)?'
Upvotes: 9
Views: 14819
Reputation: 4488
In you case 43 (1943) is considered as a not valid year. The reason is that mktime
return a time_t
type. This type is not really standardized. What the documentation said :
The
time_t
type is an integral value representing the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC. And tm_year is the number of years since 1900
This link What is ultimately a time_t typedef to? says :
time_t
represents the number of seconds since the start of the Unix epoch: midnight UTC of January 1, 1970 (not counting leap seconds). Some systems correctly handle negative time values, while others do not.
If we consider that time_t
is a signed 32 bits integer, in the best scenario you can create date between ~ 13/12/1901 and 19/1/2038
But in your case the implementation does not use the negative part of time_t
, so you cannot create date prior 1970 with mktime
.
Upvotes: 18
Reputation: 15768
You are trying to represent the date "January 2nd, 1943".
On a Unix/Linux system, this date is not representable in a time_t
value, because those systems use "January 1, 1970" as reference date.
Update:
POSIX specifies that mktime returns the time in "seconds since the Epoch" (where Epoch = 01-01-1970 00:00:00). In a strict interpretation, dates prior to Jan 1, 1970 can thus not be represented, because 'seconds since' is inherently a positive number.
ANSI/ISO C is less clear about the possibility of negative values for the result of mktime
.
Upvotes: 0
Reputation: 400174
time_t
is a 64-bit integer on your system and you're using the wrong format flag specifier to print it out. You need to use the ll
modifier to indicate that it's 64 bits:
time_t t = mktime(&stm);
printf("%lld", (int64_t)t); // This will be correct if time_t is 32 or 64 bits
Since the time is before the epoch (January 1, 1970), the time is a negative value like -851910873, which is 0xffffffffcd38df27 in hex as a 64-bit integer. When you try to print it out as a 32-bit integer, you get the upper 32 bits, which is 0xffffffff or -1 (although technically this is undefined behavior according to the C standard, so don't rely on this).
As others have mentioned, the actual size of time_t
is not specified, so you shouldn't make any assumptions about it. The safest thing to do is to always widen it to 64 bits if you really need to know how big it is.
Upvotes: 3