硬件平台STM32,软件平台Keil MDK 5.18
由于项目中需要用到UNIX时间戳和日历的来回转换,于是想到C库函数<time.h>里面有现成的函数可以使用。
于直接使用mktime和gmtime两个函数进行时间戳转换,前者把日历转为时间戳,后者把时间戳转为日历。
但是程序运行起来发现,gmtime得到的日历数据为乱码!!!
经过调试才发现,这个函数返回值是NULL啊!!!
查看反汇编代码,简直惊呆,这是什么鬼操作?
汇编代码没有函数跳转,取而代之的是MOVS R0, #0x00,直接返回0。
看到这一幕,气炸,搞了个假的库函数给我啊。
于是马上又换成另一个时间戳转转函数localtime,经测试发现这个函数工作得很好!
gmtime和localtime的区别就是,gmtime返回的是GMT标准时间,而localtime返回的是本地时间。
何为本地时间?那就是带时区转换的时间,比如北京时间是东8区,与GMT时间相差8小时。
然而MDK库函数并没有直接设置时区的函数,因此locatime返回的仍然是GMT时间。
所以在使时localtime的时候,要先把时间戳加上28800秒(8小时)再进行转换,就能得到北京时间。
最后附上日历和时间戳相互转换的代码:
日历转时间戳
日历转时间戳使用mktime函数,参考代码如下:
void date_to_timestamp(struct date *date, uint32_t *timestamp)
{time_t times;struct tm tm;tm.tm_year = date->year - 1900; //C库函数的年份是从1900开始计算tm.tm_mon = date->month - 1; //C库函数的月份是用0表示1月tm.tm_mday = date->day;tm.tm_hour = date->hour;tm.tm_min = date->minute;tm.tm_sec = date->second;times = mktime(&tm);*timestamp = times - 28800; //北京时间:东8区偏移值
}
时间戳转日历
时间戳转日历使用localtime函数,参考代码如下:
void timestamp_to_date(uint32_t timestamp, struct date *date)
{time_t times;struct tm *tm;times = timestamp + 28800;tm = localtime(×);date->year = tm->tm_year + 1900;date->month = tm->tm_mon + 1;date->day = tm->tm_mday;date->hour = tm->tm_hour;date->minute = tm->tm_min;date->second = tm->tm_sec;
}
PS:如果需要使用毫秒级的时间戳,可以直接把这个秒级的时间戳乘以1000,倒过来则除以1000。