- How do I use the C date and time functions on UNIX?
- 1 Answer 1
- Terminology
- Data types
- Program to print the current Coordinated Universal Time
- Program to print the current local time
- Program to print the current formatted Greenwich Mean Time
- Other issues to consider
- Linux: Common Time Functions
- 1.time
- 2.gmtime
- 3.ctime
- 4.asctime
- 5.localtime
- 6.mktime
- Hot Tags
How do I use the C date and time functions on UNIX?
Jon Skeet spoke of the complexity of programming dates and times at the 2009 DevDays in London. Can you give me an introduction to the ANSI C date/time functions on UNIX and indicate some of the deeper issues I should also consider when using dates and times?
1 Answer 1
Terminology
A date/time can be in two formats:
- calendar time (a.k.a. simpletime) – time as an absolute value typically since some base time, often referred to as the Coordinated Universal Time
- localtime (a.k.a. broken-down time) – a calendar time made up of components of year, month, day etc. which takes into account the local time zone including Daylight Saving Time if applicable.
Data types
The date/time functions and types are declared in the time.h header file.
Time can be stored as a whole number or as an instance of a structure:
- as a number using the time_t arithmetic type – to store calendar time as the number of seconds elapsed since the UNIX epoch January 1, 1970 00:00:00
- using the structure timeval – to store calendar time as the number of seconds and nanoseconds elapsed since the UNIX epoch January 1, 1970 00:00:00
- using the structure tm to store localtime, it contains attributes such as the following:
The tm_isdst attribute above is used to indicate Daylight Saving Time (DST). If the value is positive it is DST, if the value is 0 it is not DST.
Program to print the current Coordinated Universal Time
#include #include int main ( int argc, char *argv[] )
In the program above the function time reads the UNIX system time, subtracts that from January 1, 1970 00:00:00 (the UNIX epoch) and returns its result in seconds.
Program to print the current local time
#include #include int main ( int argc, char *argv[] ) < time_t now; struct tm *lcltime; now = time ( NULL ); lcltime = localtime ( &now ); printf ( "The time is %d:%d\n", lcltime->tm_hour, lcltime->tm_min ); return 0; >
In the program above the function localtime converts the elapsed time in seconds from the UNIX epoch into the broken-down time. localtime reads the UNIX environment TZ (through a call to the tzset function) to return the time relative to the timezone and to set the tm_isdst attribute.
A typical setting of the TZ variable in UNIX (using bash) would be as follows:
Program to print the current formatted Greenwich Mean Time
#include #include int main ( int argc, char *argv[] )
In the program above the function strftime provides specialised formatting of dates.
Other issues to consider
Linux: Common Time Functions
The following functions can all be found in: man 3 ctime.
The following test source code is used:
git clone https://github.com/rtczza/Linux_Time.git
1.time
returns the time as the number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).
On success, the value of time in seconds since the Epoch is returned. On error, ((time_t) -1) is returned, and errno is set appropriately.
Get the current time: the number of seconds that have passed since 00:00 on January 1, 1970.
#include #include int main(int argc, char** argv)
Compile and test: (as follows:)
2.gmtime
struct tm *gmtime(const time_t *timep);
The members of the tm structure are: tm_sec The number of seconds after the minute, normally in the range 0 to 59, but can be up to 60 to allow for leap seconds. tm_min The number of minutes after the hour, in the range 0 to 59. tm_hour The number of hours past midnight, in the range 0 to 23. tm_mday The day of the month, in the range 1 to 31. tm_mon The number of months since January, in the range 0 to 11. tm_year The number of years since 1900. tm_wday The number of days since Sunday, in the range 0 to 6. tm_yday The number of days since January 1, in the range 0 to 365. tm_isdst A flag that indicates whether daylight saving time is in effect at the time described. The value is positive if daylight saving time is in effect, zero if it is not, and negative if the information is not available.
Gets the current time and converts it to the format specified in the structure.
1. tm_hot denotes the time of UTC, and no time zone conversion has been seen.
2. The monthly range of tm_mon is 0-11.
3. The tm_year year is the number of years that began in 1900, so it is necessary to add 1900 when printing.
#include #include int main() < time_t t = time(NULL); printf("time :%ld \n", (long)t); struct tm *gt; gt = gmtime(&t); printf("gt->tm_sec \t:%d \n", gt->tm_sec); printf("gt->tm_min \t:%d \n", gt->tm_min); printf("gt->tm_hour \t:%d \n", gt->tm_hour); //UTC time, without time zone conversion printf("gt->tm_mday \t:%d \n", gt->tm_mday); printf("gt->tm_mon+1 \t:%d \n", gt->tm_mon+1); //Scope is 0-11 printf("gt->tm_year+1900 :%d \n", gt->tm_year+1900); //Years from 1900 printf("gt->tm_wday \t:%d \n", gt->tm_wday); printf("gt->tm_yday \t:%d \n", gt->tm_yday); printf("gt->tm_isdst \t:%d \n", gt->tm_isdst); return 0; >
Compile and test: (as shown below)
3.ctime
char *ctime(const time_t *timep);
The call ctime(t) is equivalent to asctime(localtime(t)). It converts the calendar time t into a null-terminated string of the form "Wed Jun 30 21:49:08 1993\n"
Successfully returns the time string and fails to return NULL.
Calling the ctime(t) function is equivalent to calling asctime (localtime (t) (the asctime function is described below).
The ctime function converts the time t ime to a string ending with a carriage return.
#include #include int main(int argc, char** argv)
Compile and test: (as shown below)
4.asctime
char *asctime(const struct tm *tm);
The asctime() function converts the broken-down time value tm into a null-terminated string with the same format as ctime(). The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions. The asctime_r() function does the same, but stores the string in a user-supplied buffer which should have room for at least 26 bytes.
Return value:
Successfully returns the time string and fails to return NULL.
The asctime function converts the time in struct tm format to a string ending with carriage return.
#include #include int main(int argc, char** argv) < if(2 != argc) < printf("Not Found Param ! \n"); return -1; >int param = atoi(argv[1]); time_t t= time(NULL); //Get the current time struct tm *gt; if(1 == param) gt = gmtime(&t); //Convert the current time to struct tm format: Get UTC time: No time zone conversion else gt = localtime(&t); //Convert the current time to struct tm format: Get the local time: after the time zone conversion char *asct; asct = asctime(gt); //Converting the current time to string format printf("asctime :%s",asct); return 0; >
Compile and test:
In the above test program:
1. First, the time function is used to get the local time and the time in time_t format.
2. Then the time of time_t format is taken as a parameter, and the time of struct tm format is obtained by gmtime function or localtime function.
3. Then using asctime function, the time in struct tm format is converted to a string.
The parameter is 1, which means UTC time: 07 a.m. on display.
The parameter is not 1, indicating the use of local time: the display is 15 p.m.
The asctime function returns the same string format as the ctime function.
The difference is that the input format is different:
asctime function: time to enter struct tm format.
ctime function: Enter the time_t format.
5.localtime
struct tm *localtime(const time_t *timep);
The localtime() function converts the calendar time timep to broken-down time representation, expressed relative to the user's specified timezone. The function acts as if it called tzset(3) and sets the external variables tzname with information about the current timezone, timezone with the difference between Coordinated Universal Time (UTC) and local standard time in seconds, and daylight to a nonzero value if daylight savings time rules apply during some part of the year. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The localtime_r() function does the same, but stores the data in a user-supplied struct. It need not set tzname, timezone, and daylight.
Gets the current time and converts it to the format specified in the structure.
1. tm_hot represents local time and passes through time zone conversion.
2. The monthly range of tm_mon is 0-11.
3. The tm_year year is the number of years that began in 1900, so it is necessary to add 1900 when printing.
#include #include int main() < time_t t = time(NULL); printf("time :%ld \n", (long)t); struct tm *gt; gt = localtime(&t); printf("gt->tm_sec \t:%d \n", gt->tm_sec); printf("gt->tm_min \t:%d \n", gt->tm_min); printf("gt->tm_hour \t:%d \n", gt->tm_hour); //It's local time, after time zone conversion. printf("gt->tm_mday \t:%d \n", gt->tm_mday); printf("gt->tm_mon+1 \t:%d \n", gt->tm_mon+1); //Scope is 0-11 printf("gt->tm_year+1900 :%d \n", gt->tm_year+1900); //Years from 1900 printf("gt->tm_wday \t:%d \n", gt->tm_wday); printf("gt->tm_yday \t:%d \n", gt->tm_yday); printf("gt->tm_isdst \t:%d \n", gt->tm_isdst); return 0; >
Compile and test:
The difference between gmtime and localtime functions is:
gmtime: Get UTC time, no time-out zone conversion.
Local time: Gets the local time and transits into and out of the time zone.
6.mktime
time_t mktime(struct tm *tm);
The mktime() function converts a broken-down time structure, expressed as local time, to calendar time representation. The function ignores the values supplied by the caller in the tm_wday and tm_yday fields. The value speci‐ fied in the tm_isdst field informs mktime() whether or not daylight saving time (DST) is in effect for the time supplied in the tm structure: a positive value means DST is in effect; zero means that DST is not in effect; and a negative value means that mktime() should (use timezone information and system databases to) attempt to determine whether DST is in effect at the specified time. The mktime() function modifies the fields of the tm structure as follows: tm_wday and tm_yday are set to values determined from the contents of the other fields; if structure members are outside their valid interval, they will be normalized (so that, for example, 40 October is changed into 9 November); tm_isdst is set (regardless of its initial value) to a positive value or to 0, respectively, to indicate whether DST is or is not in effect at the specified time. Calling mktime() also sets the external variable tzname with information about the current timezone.
Return value:
Time in time_t format is returned successfully, and time_t — 1 is returned unsuccessfully.
The mktime function converts the time in struct tm format to time_t format.
#include #include void Print(struct tm *gt) < printf("gt->tm_sec \t:%d \n", gt->tm_sec); printf("gt->tm_min \t:%d \n", gt->tm_min); printf("gt->tm_hour \t:%d \n", gt->tm_hour); printf("gt->tm_mday \t:%d \n", gt->tm_mday); printf("gt->tm_mon+1 \t:%d \n", gt->tm_mon+1); printf("gt->tm_year+1900 :%d \n", gt->tm_year+1900); printf("gt->tm_wday \t:%d \n", gt->tm_wday); printf("gt->tm_yday \t:%d \n", gt->tm_yday); printf("gt->tm_isdst \t:%d \n", gt->tm_isdst); > int main(int argc, char **argv) < if(2 != argc) < printf("Not Found Param ! \n"); return -1; >int param = atoi(argv[1]); //input parameter time_t t = time(NULL); //Time to get time_t format (current time) printf("time :%ld \n", (long)t); struct tm *gt; //Time to convert time_t format to struct tm format if(1 == param) gt = gmtime(&t); else gt = localtime(&t); Print(gt); time_t t2; t2 = mktime(gt); //Time to convert struct tm format to time_t format printf("time2 :%ld \n", (long)t2); return 0; >
Compile and test:
It should be noted that the struct tm parameter input to the mktime function is the local time (that is, the time after the time zone conversion).
As can be seen from the screenshot above:
When the input parameter is not 1:
Local time after conversion is used. After the transformation of mktime function, the two timestamps are the same.
When the input parameter is 1:
UTC time after gmtime conversion. After mktime function conversion, the two timestamps are different.
Posted on Tue, 27 Aug 2019 08:13:26 -0400 by gj6kings
Hot Tags
- Java — 7906
- Database — 3176
- Python — 3103
- Attribute — 2963
- Programming — 2938
- Javascript — 2788
- Spring — 2575
- xml — 2270
- Android — 2243
- Linux — 2204
- JSON — 2150
- less — 2137
- network — 2115
- github — 2063
- MySQL — 1760
- SQL — 1616
- PHP — 1559
- encoding — 1360
- Mobile — 1172
- Apache — 1137