localtime函数在不同平台使用注意
1.写在前面
localtime函数是C语言标准库中时间库“time.h”中获取系统带时区时间的函数,获得的时间最终以“strcut tm”的格式输出。对于通用操作系统如Windows、Linux中调用该函数,那么获得的时间就是带时区的,这一点毫无疑问。而在一些嵌入式场合,我们也会面临将时间戳转换成“年月日时分秒”格式,如ST早期的STM32 RTC就是只提供一个时间戳计时器;假若不额外自行编写换算函数,也是可以使用“轮子”,直接调用该函数的。在以往开发非联网或者国内使用时,并未在意到时区问题;在实际论证下,有些嵌入式场合localtime获得的时间并不带时区,如MCU直接调用。
2.localtime调用
时间库中与localtime对应,获取不带时区的系统时间函数是“gmtime”,下面在Windows和Linux平台下对比两者情况。另外,对于衍生localtime(gmtime)函数localtime_r、localtime_s用法是一样的,只是localtime_r和localtime_s是可重入函数,前者用于Linux平台,后者用于Windows平台。
2.1 localtime Windows调用
编译工具为VS2015,代码如下。
#include "stdafx.h"
#include "time.h"
#include "stdio.h"
int main(int argc, char **argv)
{
time_t time_cnt = { 0 };
struct tm time_sct;
time_cnt = time(NULL);
printf("time_cnt=%d\n", time_cnt);
gmtime_s(&time_sct,&time_cnt);
printf("Call gmtime, the time is:%d-%d-%d %d:%d:%d\n", time_sct.tm_year - 100, time_sct.tm_mon + 1, time_sct.tm_mday, time_sct.tm_hour, time_sct.tm_min, time_sct.tm_sec);
localtime_s(&time_sct,&time_cnt);
printf("Call localtime, the time is:%d-%d-%d %d:%d:%d\n", time_sct.tm_year - 100, time_sct.tm_mon + 1, time_sct.tm_mday, time_sct.tm_hour, time_sct.tm_min, time_sct.tm_sec);
getchar();
return 0;
}
执行结果如图,两者相差8小时,说明localtime已经带了时区执行。
2.2 localtime Linux调用
编辑器用Vi,编译器为g++,源码如下。
#include <time.h>
#include <stdio.h>
int main(int argc, char **argv)
{
time_t time_cnt = {0};
struct tm *time_sct = NULL;
time_cnt = time(NULL);
printf("time_cnt=%d\n", time_cnt);
time_sct = gmtime(&time_cnt);
printf("Call gmtime, the time is:%d-%d-%d %d:%d:%d\n", time_sct->tm_year-100,time_sct->tm_mon+1,time_sct->tm_mday,time_sct->tm_hour, time_sct->tm_min, time_sct->tm_sec);
time_sct = localtime(&time_cnt);
printf("Call localtime, the time is:%d-%d-%d %d:%d:%d\n",time_sct->tm_year-100,time_sct->tm_mon+1,time_sct->tm_mday,time_sct->tm_hour, time_sct->tm_min, time_sct->tm_sec);
return 0;
}
执行结果如图,与Windows一致,也验证了localtime的时区计算功能。
2.3 嵌入平台调用
在嵌入式MCU上运行,分别在裸机和FreeRTOS中调用,代码与上述一致,通过串口打印时间。得出的结果如下图。
实际证明,两者函数执行结果一致,带时区功能的localtime并没有实现时区转换,此时的时间都是UTC时间,即0时区的时间。另外,也可以将打印的时间戳(1545002474)通过转换工具转换验证,得到的北京时间是比上图中的时间快8小时,证实上面时间是0时区时间。
2.4 其他嵌入平台
其他嵌入式平台暂未验证,如嵌入式Linux、各类RTOS等。在实际应用中,如涉及到时区时,使用时间(time)库函数时需格外注意。
3. 结论
在嵌入式平台下调用时间库函数,需注意时区问题。