Date and time

The header file <time.h>

The functions and structures, of the C Standard Library, to handle time and dates are declared in the header file <time.h>.

Calculating a duration

The function clock_t clock() returns the number of times the clock (Linked to the program) ticked. The clock ticks (Its tick counter is incremented) the number of times represented by the macro CLOCKS_PER_SEC, each second. Usually the clock starts ticking (Its tick counter starting at 0) right at the start of the program, but that may vary. However, we know it starts before the program begins its execution.

The type clock_t is a typedef of a primitive type and should be used to retrieve the value returned by the function clock.

As it is not guaranteed that the tick counter of the clock starts at 0 when the execution of the program begins, to calculate a duration, we should always calculate the difference between two values returned by the function clock.

To convert a number of ticks of the clock to seconds, we must divide it by the number of times the clock ticks each second (CLOCKS_PER_SEC). To convert it to milliseconds, we must divide it by the number of times the clock ticks each second and then multiply it by 1000...

Note that the value of the macro CLOCKS_PER_SEC varies depending on the compiler used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h> #include <time.h> int main() { clock_t start = clock(); // Executes some instructions unsigned c3 = 1; for(unsigned c = 0; c < 10000; c++) { c3 += c; for(unsigned c2 = 1; c2 < 10000; c2++) c3 *= c2; } // We calculate the number of ticks between the beginning and the end of the executions. clock_t diff = clock() - start; // We convert the number of ticks to seconds. double nbSeconds = diff / (double)CLOCKS_PER_SEC; printf("The instructions has been executed in %f seconds.\n", nbSeconds); printf("The instructions has been executed in %f milliseconds.\n", nbSeconds * 1000); printf("The instructions has been executed in %f minutes.\n", nbSeconds / 60); return 0; }

Retrieving the current time

Time is represented as a duration between a moment in time used as reference, called epoch, and the moment represented. The function time_t time(time_t *timer) returns, and assigns the variable pointed by the pointer it receives as argument, with the number of seconds elapsed since its epoch. The epoch it uses depends on the compiler, but it often is, for historic reasons, midnight the January 1, 1970, UTC timezone. When this is the epoch, the value returned is called the unix timestamp.

For those who do not know, UTC is the timezone of Greenwich (GMT). If your local timezone is UTC-5, that means your local time is 5 hours less than in the UTC timezone and if it is UTC+5, that means your local time is 5 hours ahead of the time in the UTC timezone.

Note that time_t is a typedef of a primitive type and it should be used to retrieve the value returned by the function time. Also, if we give the function time the address 0 as argument, it only returns the value.

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h> #include <time.h> int main() { time_t t = time(NULL); printf("The value returned by time(NULL): %ld\n", t); return 0; }

The time structure

The structure struct tm is a structure used to conveniently represent a moment in time. Here are its members (Of type int):

MemberRepresenting the number of
tm_secSeconds after the minute
tm_minMinutes after the hour
tm_hourHours since midnight
tm_mdayDay of the month
tm_monMonths since January
tm_yearYears since 1900
tm_wdayDays since Sunday
tm_ydayDays since January
tm_isdstIs daylight saving time (>0: yes, ==0: no, <0: ?)

We can convert a value of type time_t returned by the function time (Relatively to the timezone of the machine) to a structure of type tm, using the function struct tm * localtime(const time_t * timer). The argument is a pointer to a variable containing a value returned by the function time and the value returned is a pointer to a structure of type tm, containing the information about the time, in the local timezone.

The structure pointed by the returned pointer may be altered by following calls to the function localtime or gmtime.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h> #include <time.h> int main() { time_t nbSec = time(NULL); struct tm timeData = *localtime(&nbSec); puts("Right now, the time is"); printf("%d:%d, %d/%d/%d\n", timeData.tm_hour, timeData.tm_min, timeData.tm_mday, timeData.tm_mon+1, timeData.tm_year + 1900); return 0; }

We can use, instead of localtime, the function struct tm * gmtime(const time_t * timer) to convert a value returned by the function time, into a structure of type tm, relatively to the UTC timezone (GMT). It works the same way as localtime.

An easy way to obtain a structure of type tm representing the current time in the UTC timezone we want, is to subtract/add hours (3600 seconds) to the value returned by the function time, before converting it to a tm structure using the function gmtime. As an example, for the timezone UTC-6, we subtract (6 * 3600) seconds to the value returned by the function time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h> #include <time.h> int main() { time_t nbSec = time(NULL); // Retrieves information about the current time in UTC timezone. struct tm timeData = *gmtime(&nbSec); puts("The time in UTC timezone:"); printf("%d:%d, %d/%d/%d\n", timeData.tm_hour, timeData.tm_min, timeData.tm_mday, timeData.tm_mon+1, timeData.tm_year + 1900); puts("The time in UTC+9 timezone:"); // Adds 9 hours to the current time. nbSec = time(NULL) + (9 * 3600); // Retrieves information about the current time in UTC+9 timezone. timeData = *gmtime(&nbSec); printf("%d:%d, %d/%d/%d\n", timeData.tm_hour, timeData.tm_min, timeData.tm_mday, timeData.tm_mon+1, timeData.tm_year + 1900); return 0; }

Note that we can convert a structure of type tm into a value of type time_t, representing the number of seconds elapsed since the epoch used by the function time, with the function time_t mktime(struct tm * timeStruct).

If we want to retrieve the name of the month, this can be done by simply defining an array containing strings with the name of the months and retrieve them using the number of the month as index.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h> #include <time.h> char *monthNames[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; int main() { time_t nbSecSinceEpoch = time(NULL); struct tm timeData = *localtime(&nbSecSinceEpoch); puts("The current date:"); printf("%s %d, %d\n", monthNames[timeData.tm_mon-1], timeData.tm_mday, timeData.tm_year + 1900); return 0; }