We can declare a variable to hold the current time from the system using:
time_t now = time(0);
time(0)
can also be use in genera
The standard doesn't define what type time_t
is; it only has to be a real type capable of representing times. It could be an integer type or a floating-point type (it can't be complex -- fortunately). And it's not necessarily a number of seconds, or milliseconds, or any simple units. It could in principle use ranges of bits to represent months, seconds, days, hours, minutes, and years in that order in binary coded decimal. The most common representation is a 32-bit or 64-bit signed integer representing seconds since 1970-01-01 00:00:00 UTC.
If you want a completely portable way to print a time_t
value, you can detect what kind of type time_t
is:
#include <stdio.h>
#include <time.h>
#include <stdint.h>
int main(void) {
time_t now = time(NULL);
printf("At the sound of the tone, the time will be ... \a");
if ((time_t)1 / 2 != 0) {
// time_t is a floating-point type; convert to long double
printf("%Lf\n", (long double)now);
}
else if ((time_t)-1 > (time_t)0) {
// time_t is an unsigned integer type
printf("%ju\n", (uintmax_t)now);
}
else {
// time_t is a signed integer type
printf("%jd\n", (intmax_t)now);
}
}
This assumes a C99 or later implementation. If you're stuck with a pre-C99 implementation that doesn't support <stdint.h>
and/or the %ju
and %jd
formats (which you can detect this by testing __STDC_VERSION__
), you can convert to long
or unsigned long
rather than [u]intmax_t
. (MinGW probably won't handle printing a long double
value correctly, but MinGW uses a signed integer type for time_t
so that's not an issue.)
This will print a raw value that isn't meaningful unless you happen to know how time_t
is represented (both what type it is and how it represents the current time). On my system, the current time is 1416589039
, which is the number of seconds since 1970-01-01 00:00:00 UTC (a very common representation).
If you want to know what time it is rather than the raw value returned by the time()
function, you should use the functions in <time.h>
to generate a human-readable representation of the current time. For example:
#include <stdio.h>
#include <time.h>
#include <stdint.h>
int main(void) {
time_t now = time(NULL);
char s[100];
strftime(s, sizeof s, "%F %H:%M:%S %Z", localtime(&now));
printf("The time is now %s\n", s);
}
which prints (at the moment on my system):
The time is now 2014-11-21 08:57:19 PST
time_t
is defined by C standard, C11, 7.27.1/3 as:
[...] which are real types capable of representing times;
That means it could be int, long, unsigned long, double or any other real type. Basically it's an implementation's choice. Similarly, it doesn't define what units time_t
returns either, C11, 7.27.2.4/3:
The time function returns the implementation’s best approximation to the current calendar time. The value (time_t)(-1) is returned if the calendar time is not available. If timer is not a null pointer, the return value is also assigned to the object it points to.
You'll have to read what your implementation says. The glibc implementation I have on my Linux says, the unit returned by time_t is in seconds. So you could convert it to uintmax_t
and print:
time_t tvalue = time(0);
printf("%ju", (uintmax_t)tvalue);
Or you could use difftime() which returns a double
as difference between two time_t
values so that you don't have to worry about the underlying type of time_t
.
On most system time_t is define on the same number of bit than integer and is always positive.
In this case you can use:
printf("time: %u", (unsigned int) time(0));
looking into the header file(s) for the time function, you will see that the parameter can be one of two things NULL or address of time_t variable.
The time() function results for both the parameter and the returned value is the elapsed time, in seconds, since the epoch (currently Jan 1, 1970 00:00 am UTC.) The sizing of the value (on older systems) was 4 bytes (32bits). with recent RTC (RealTimeClock) hardware available, the value 'may' be 8 bytes (64bits) . in any case the value in is seconds since the epoch.
The 4 byte time values will overflow in 2038, so efforts are being made to either 1) make the time value a larger size or 2) shift the epoch time forward to Jan 1 2000 00:00 am. ( a temporary fix when using older hardware )
the changing of the time values to 8 bytes is the current preferred method.
here is a specific quote from google:
"At 03:14:08 UTC on 19 January 2038, 32-bit versions of the Unix time stamp will cease to work" to paraphase the rest of the quote: the 32 bit value will overflow.
The functions that handle time, like localtime() strtotime(). etc and the related structs, like tm, are setup to use what ever the system they are running on is returning from the time() function.
All the processing of the value from the time function should be done using the available functions rather than handling the raw value.
As already said, standard does not specifies what time_t is. If you want to be sure to use it in a portable way, first convert it to long and then print it as a long. That way your program won't suffer the Year 2038 problem even if 32 bits architectures are still available at that time :-) ...
time_t t = time(NULL);
long lt = (t > 0) ? t : (unsigned int) t;
printf("%ld", lt);
It should work for time_t being a 32 bits signed of insigned integer or a 64 bit integer. My formule will break when time_t will be a negative 64 bits integer, but contact me at that time and I should then be wise enough to find a better solution :-)
EDIT :
As noted by chux this is bad if int is only 16 bits. Here is a robust even if ugly way
union {
long l;
unsigned char[1] c;
} ul;
time_t t = time(NULL);
ul.l = 0;
ul.c[0] = 255;
if (ul.l < 0) { /* endianness test */
ul.l = 0;
memcpy(&ul.l, t&, sizeof(time_t));
}
else {
ul.l = 0;
memcpy(&ul.l + sizeof(long) - sizeof(time_t), &t, sizeof(time_t));
}
printf("%lu", (unsigned long) ul.l);
It should work in any configuration provided sizeof(long)>=sizeof(time_t)
EDIT 2:
chux's proposal seems to work on any reasonable cases. There are certainly pathological cases where it could break but on a normal implementation
time_t t = time(NULL);
long lt = (t > 0) ? t : t * 1u;
printf("%ld", lt);
should give correct result.