settimeofday 设置时区不起作用

使用settimeofday 设置时区不起作用,代码如下:

void show_time(struct tm *p_tm)
{
	printf("%d-%02d-%02d %02d:%02d:%02d\n",
		p_tm->tm_year+1900,p_tm->tm_mon+1,p_tm->tm_mday,
		p_tm->tm_hour,p_tm->tm_min,p_tm->tm_sec);
}

int set_time(struct tm *p_tm,int tzone)
{
	struct timeval tv;
	struct timezone tz;
	
	tv.tv_sec = mktime(p_tm);
	tv.tv_usec = 0;

	tz.tz_minuteswest = tzone*-60;
	tz.tz_dsttime = 0;
	DEBUG_PRINT("tz:%d\n",tz.tz_minuteswest);
	if(settimeofday(&tv, &tz)<0)
	{
		DEBUG_PRINT("settimeofday failed!\n");
		return -1;
	}
	time_t now;
	time(&now);
	struct tm t_tm;
	localtime_r(&now, &t_tm); //换算成本地时间以验证时区是否设置成功
	show_time(&t_tm);	
	return 0;
}

测试设置时间:2019-03-21 8:00:00 tzone = 8
期望打印时间:2019-03-21 16:00:00
实际打印时间:2019-03-21 8:00:00

内核版本:3.18.21
从实际打印时间看出,时区设置不生效,到底是为什么呢?
查看手册,man settimeofday 发现

The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.
timezone structure 的作用已经被废弃,tz 参数一般要设为NULL

好吧,被废弃了?也不知道是从哪个版本开始废弃的。

那么还有什么办法可以设置时区?
使用 tzset ,使用tzset 前需要设置TZ 环境变量。

void set_tz(int tz)
{	
	char tzstr[256] = {0};		
	int tzhour = -tz;
		
	snprintf(tzstr,sizeof(tzstr),"GMT%+02d",tzhour);
	if(setenv("TZ", tzstr, 1)!=0)
	{
		DEBUG_PRINT("setenv failed \n");
	}
	DEBUG_PRINT("time zone:%s\n",tzstr);
	tzset();
}
int set_time(struct tm *p_tm,int tzone)
{
	struct timeval tv;
	struct timezone tz;
	
	tv.tv_sec = mktime(p_tm);
	tv.tv_usec = 0;

	tz.tz_minuteswest = tzone*-60;
	tz.tz_dsttime = 0;
	DEBUG_PRINT("tz:%d\n",tz.tz_minuteswest);
	if(settimeofday(&tv, &tz)<0)
	{
		DEBUG_PRINT("settimeofday failed!\n");
		return -1;
	}	
	set_tz(tzone);

	time_t now;
	time(&now);
	struct tm t_tm;
	localtime_r(&now, &t_tm);
	show_time(&t_tm);
		
	return 0;
}

测试设置时间:2019-03-21 8:00:00 tzone = 8
期望打印时间:2019-03-21 16:00:00
实际打印时间:2019-03-21 16:00:00 (符合期望!)

这下是正确了!但是在中断中用date 命令查看时间,结果却还是时区不生效!
#date
#Thu Mar 21 8:02:48 GMT 2019

这是为什么呢?
查了很多文章,终于找到了最佳答案:
Linux在C语言下的时区设置与修改(三) - chinaclock的专栏 - CSDN博客
https://blog.csdn.net/chinaclock/article/details/43795651

总结来说就是:子进程里的TZ 变量对父进程不起作用。

你可能感兴趣的:(Linux,OpenWrt)