1 概要
时区TZ环境变量,对时间相关函数的影响,关于TZ的介绍查看
2 gettimeofday
int gettimeofday(struct timeval *tv, struct timezone *tz);
这个函数获取的是UTC时间,与TZ环境变量无关。
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
在gettimeofday中tz_minuteswest和 tz_dsttime一直返回0.
3 gmtime
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
gmtime是将timep(utc时间)秒数转化为tm结构时区为零的年月日时分秒时间,与系统时区没有关系,
改变TZ环境变量对这个函数没有影响。
比如,当前北京时间是2021-02-08 09:16:03,那么utc时间应该是1612746963(2021-02-08 01:16:03),
如果time = 1612746963,那么gmtime(&time),返回的应该是2021-02-08 01:16:03
4 localtime
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
localtime是将timep(utc时间)秒数转化为tm结构时区为本地的年月日时分秒时间,与系统时区有关系,
改变TZ环境变量对这个函数有影响。
比如,当前北京时间是2021-02-08 09:16:03,那么utc时间应该是1612746963(2021-02-08 01:16:03),
当time = 1612746963。
例1:如果TZ=CST-08:00为东8区(中国时区),那么localtime(&time),返回的应该是2021-02-08 09:16:03。
例2:如果TZ=UTC-00:00为零时区(本初子午线地区),那么localtime(&time),返回的应该是2021-02-08 01:16:03。
5 mktime
time_t mktime(struct tm *tm);
将当前本地时间转换为UTC时间,和时区有关系。
比如当前本地时间为2021-02-08 09:16:03。
当前时区为东八区,那么调用mktime得到的utc时间1612746963。
当前时区是0时区,那么待用mktime得到的utc时间应该是 1612775763(1612746963+8*60*60)。
6 tzset
void tzset (void);
extern char *tzname[2];
extern long timezone;
如果TZ=CST-8:00,调用tzset ()函数后,
tzname[0] = CST
tzname[1] = CST
timezone = -28800
7 测试代码
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <sys/time.h>
#if 0
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
time_t mktime(struct tm *tm);
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
void tzset (void);
extern char *tzname[2];
extern long timezone;
extern int daylight;
#endif
void print_tm(struct tm *tm)
{
printf("tm_year = %04d\n", tm->tm_year);
printf("tm_mon = %02d\n", tm->tm_mon);
printf("tm_mday = %02d\n", tm->tm_mday);
printf("tm_hour = %02d\n", tm->tm_hour);
printf("tm_min = %02d\n", tm->tm_min);
printf("tm_sec = %02d\n", tm->tm_sec);
printf("tm_wday = %d\n", tm->tm_wday);
printf("tm_yday = %03d\n", tm->tm_yday);
printf("tm_isdst = %d\n", tm->tm_isdst);
printf("%04d-%02d-%02d %02d:%02d:%02d\n",\
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,\
tm->tm_hour, tm->tm_min, tm->tm_sec);
}
void print_tv(struct timeval *tv)
{
printf("tv->tv_sec = %ld\n", tv->tv_sec);
printf("tv->tv_usec = %ld\n", tv->tv_usec);
}
void print_tz(struct timezone *tz)
{
printf("tz->tz_minuteswest = %d\n", tz->tz_minuteswest);
printf("tz->tz_dsttime = %d\n", tz->tz_dsttime);
}
void print_tz_info(void)
{
printf("tzname[0] = %s\n", tzname[0]);
printf("tzname[1] = %s\n", tzname[1]);
printf("timezone = %ld\n", timezone);
}
int main()
{
struct tm *ptm;
struct tm tm;
struct timeval tv;
struct timezone tz;
time_t time;
int ret;
ret = gettimeofday(&tv, &tz);
if(ret) {
printf("------------gettimeofday Err\n");
return ret;
}
printf("+++++++++++++++++++++gettimeofday+++++++++++++++++++++\n");
print_tv(&tv);
print_tz(&tz);
time = tv.tv_sec;
printf("+++++++++++++++++++++localtime+++++++++++++++++++++\n");
ptm = localtime(&time);
print_tm(ptm);
printf("+++++++++++++++++++++localtime_r+++++++++++++++++++++\n");
localtime_r(&time, &tm);
print_tm(&tm);
printf("+++++++++++++++++++++localtime_r -> mktime+++++++++++++++++++++\n");
printf("mktime = %ld\n", mktime(&tm));
printf("+++++++++++++++++++++gmtime+++++++++++++++++++++\n");
ptm = gmtime(&time);
print_tm(ptm);
printf("+++++++++++++++++++++gmtime_r+++++++++++++++++++++\n");
gmtime_r(&time, &tm);
print_tm(&tm);
printf("+++++++++++++++++++++print_tz_info+++++++++++++++++++++\n");
//tzset();
print_tz_info();
return 0;
}
打印信息:
# date
Mon Feb 8 10:36:43 CST 2021
# ./test
+++++++++++++++++++++gettimeofday+++++++++++++++++++++
tv->tv_sec = 1612751804
tv->tv_usec = 419185
tz->tz_minuteswest = 0
tz->tz_dsttime = 0
+++++++++++++++++++++localtime+++++++++++++++++++++
tm_year = 0121
tm_mon = 01
tm_mday = 08
tm_hour = 10
tm_min = 36
tm_sec = 44
tm_wday = 1
tm_yday = 038
tm_isdst = 0
2021-02-08 10:36:44
+++++++++++++++++++++localtime_r+++++++++++++++++++++
tm_year = 0121
tm_mon = 01
tm_mday = 08
tm_hour = 10
tm_min = 36
tm_sec = 44
tm_wday = 1
tm_yday = 038
tm_isdst = 0
2021-02-08 10:36:44
+++++++++++++++++++++localtime_r -> mktime+++++++++++++++++++++
mktime = 1612751804
+++++++++++++++++++++gmtime+++++++++++++++++++++
tm_year = 0121
tm_mon = 01
tm_mday = 08
tm_hour = 02
tm_min = 36
tm_sec = 44
tm_wday = 1
tm_yday = 038
tm_isdst = 0
2021-02-08 02:36:44
+++++++++++++++++++++gmtime_r+++++++++++++++++++++
tm_year = 0121
tm_mon = 01
tm_mday = 08
tm_hour = 02
tm_min = 36
tm_sec = 44
tm_wday = 1
tm_yday = 038
tm_isdst = 0
2021-02-08 02:36:44
+++++++++++++++++++++print_tz_info+++++++++++++++++++++
tzname[0] = CST
tzname[1] = CST
timezone = -28800
#