preface
When we are developing on linux platform, we will basically encounter time-related operations. This paper analyzes and summarizes the commonly used time-related structures and interfaces.
Common types and structure definitions
timespec
prototype
struct timespec { __time_t tv_sec; /* Seconds. second */ __syscall_slong_t tv_nsec; /* Nanoseconds. nanosecond*/ };
explain
The structure only includes seconds and nanoseconds, and has no other meaning, such as the number of seconds since 1970. Just a storage space. Is clock_ The output parameter of gettime.
clock_gettime
prototype
int clock_gettime (clockid_t __clock_id, struct timespec *__tp);
explain
According to clock_ ID (system clock) to get the current time.
Parameter description
clock_ Enumeration description of common values of ID
enum | explain |
---|---|
CLOCK_REALTIME | The current time of the system is calculated from January 1, 1970 |
CLOCK_MONOTONIC | Elapsed time from system startup time |
CLOCK_PROCESS_CPUTIME_ID | Running time of this process |
CLOCK_THREAD_CPUTIME_ID | The running time of this thread |
Program example
#include <time.h> #include <stdio.h> #include <sys/time.h> int main(void) { struct timespec tsp; printf("CLOCK REALTIME time:\n"); clock_gettime(CLOCK_REALTIME, &tsp); printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec); printf("-----------------------\n"); printf("CLOCK MONOTONIC time:\n"); clock_gettime(CLOCK_MONOTONIC, &tsp); printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec); printf("-----------------------\n"); printf("CLOCK PROCESS CPUTIME ID time:\n"); clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tsp); printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec); printf("-----------------------\n"); printf("CLOCK THREAD CPUTIME ID time:\n"); clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tsp); printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec); printf("-----------------------\n"); return 0; }
Operation results:
CLOCK REALTIME time: sec:1644155596, nsec:748701786 ----------------------- CLOCK MONOTONIC time: sec:12526311, nsec:817330221 ----------------------- CLOCK PROCESS CPUTIME ID time: sec:0, nsec:585929 ----------------------- CLOCK THREAD CPUTIME ID time: sec:0, nsec:590570
timeval
prototype
struct timeval { __time_t tv_sec; /* Seconds. second*/ __suseconds_t tv_usec; /* Microseconds. Microsecond*/ };
explain
This structure only includes seconds and microseconds, and has no other meaning, such as the number of seconds since 1970. Just a storage space. Parameter for gettimeofday.
timezone
prototype
struct timezone { int tz_minuteswest; /* Minutes west of GMT. How many minutes is it from Greenwich */ int tz_dsttime; /* Nonzero if DST is ever in effect. Daylight saving time status */ };
explain
The structure is time zone related information, which is rarely used, and the output parameter of gettimeofday. Generally, we can also directly pass in NULL
gettimeofday
prototype
int gettimeofday(struct timeval *tv, struct timezone *tz);
explain
Get the current time, which is UTC time, seconds + microseconds and time zone information since 1970.
Parameter description
parameter | type | explain |
---|---|---|
tv | struct timeval * | UTC, reference time |
tz | struct timezone * | Current time zone information |
Return value
0 is returned for success, and - 1 is returned for failure. The error reason exists in errno.
Program example
#include <time.h> #include <stdio.h> #include <sys/time.h> int main(void) { struct timeval tv; struct timezone tz; printf("gettimeofday time:\n"); gettimeofday(&tv, &tz); printf("tv_sec:%ld tv_usec:%ld\n", tv.tv_sec, tv.tv_usec); printf("tz:%d %d\n", tz.tz_dsttime, tz.tz_minuteswest); return 0; }
Operation results:
gettimeofday time: tv_sec:1644156383 tv_usec:513679 tz:0 0
time_t
prototype
typedef long time_t;
explain
This type is actually long int, which is used to store the number of seconds. It is the input parameter and return value of the time function.
time
prototype
time_t time(time_t *t)
explain
This function will return the number of seconds elapsed since 0:00 on January 1, 1970. If t is a non null pointer, the function will also store the return value in the memory indicated by the T pointer.
Parameter description
parameter | type | explain |
---|---|---|
t | time_t * | Second storage pointer returned |
Return value
The number of seconds is returned if successful, and - 1 is returned if failed. The error reason exists in errno.
Program example
#include <time.h> #include <stdio.h> #include <sys/time.h> int main(void) { time_t timep1, timep2; timep1 = time(NULL); time(&timep2); printf("timep1:%ld timep2:%ld\n", timep1, timep2); return 0; }
Operation results:
timep1:1644157011 timep2:1644157011
tm
prototype
struct tm { int tm_sec; /* Seconds. [0-60] (1 leap second) */ int tm_min; /* Minutes. [0-59] */ int tm_hour; /* Hours. [0-23] */ int tm_mday; /* Day. [1-31] */ int tm_mon; /* Month. [0-11] Note: 0 represents January, and so on*/ int tm_year; /* Year - 1900. This value is the actual year minus 1900*/ int tm_wday; /* Day of week. [0-6] Note: 0 represents Monday, and so on*/ int tm_yday; /* Days in year.[0-365] The number of days from January 1 of each year, where 0 represents January 1, and so on*/ int tm_isdst; /* DST. [-1/0/1] Xia Lingshi identifier*/ };
explain
This type is used to describe the time and date used in the real world, including year, day, hour, minute, second, week, etc. it is the return value of localtime
localtime
prototype
struct tm *localtime(const time_t *timep);
explain
Convert the current seconds indicated by the parameter timep into the time and date representation method used in the real world, and the result is returned.
Parameter description
parameter | type | explain |
---|---|---|
timep | time_t | Current UTC seconds |
Return value
The year, month, day, hour, minute, second, week, etc. corresponding to the current UTC seconds.
Program example
#include <time.h> #include <stdio.h> #include <sys/time.h> int main(void) { time_t timep; struct tm *p; timep = time(NULL); printf("timep:%ld\n", timep); p = localtime(&timep); // Deal with the year and month accordingly printf("%d-%d-%d %d:%d:%d \n", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); return 0; }
Operation results:
timep:1644157741 2022-2-6 22:29:1
localtime_r
In the program example of localtime above, it can be found that the return value of localtime is of type struct tm *, that is, a pointer to type struct tm, which will not cause problems such as memory leakage. This is because the return value of localtime actually points to a static variable, which is the static struct tm type data defined in the static library. Obviously, Because the program uses static variables, the localtime cannot be re entered, that is, it is not ready-made security. It will not bring any hidden dangers to general application scenarios, but it will bring problems to places with high real-time requirements, because calling localtime many times will cause the return value to be overwritten.
For example:
Two threads A and B call the localtime function at the same time:
Time 1: thread A calls the localtime function to get A pointer, and the value stored in tm is updated to value-A
Time 2: thread B calls the localtime function to get a pointer, and the value stored in tm is updated to value-B
Time 3: thread A refers to the pointer returned by localtime (for example, printf outputs A field). At this time, the value in static struct tm is actually value-b, not the expected value-a
Time 4: thread B refers to the pointer returned by localtime. At this time, the value in static struct tm is actually value-b
Therefore, in order to solve the problem that localtime cannot be re entered, localtime appears_ r.
prototype
struct tm *localtime_r(const time_t *timep, struct tm *result);
explain
To call localtime, you only need to pass in the pointing time_ A constant pointer to t;
Call localtime_t not only needs to pass in pointing to time_ A constant pointer to t also needs to pass in a pointer to struct tm, and the result will be stored in the struct tm object pointed to by result;
Program example
#include <time.h> #include <stdio.h> #include <sys/time.h> int main(void) { time_t timep; struct tm *p; struct tm res; timep = time(NULL); printf("timep:%ld\n", timep); localtime_r(&timep, &res); printf("%d-%d-%d %d:%d:%d \n", 1900 + res.tm_year, 1 + res.tm_mon, res.tm_mday, res.tm_hour, res.tm_min, res.tm_sec); return 0; }
Operation results:
timep:1644158806 2022-2-6 22:46:46
Summary
The above are the definitions of common structures, variables and interfaces related to time under linux platform. For more detailed description, please refer to the relevant source code definitions.