小沃最近写代码遇到需要在单片机中使用时间与时间戳互转的需求,随即自己写了一个,使用方法尽可能的模仿linux c中的mktime与localtime函数,代码如下:
time.h
#ifndef __TIME_H__ #define __TIME_H__ struct tm { int tm_year; // 年份,其值等于实际年份减去1900 int tm_mon; // 月份(从一月开始,0代表一月) - 取值区间为[0,11] int tm_mday; // 一个月中的日期 - 取值区间为[1,31] int tm_hour; // 时 - 取值区间为[0,23] int tm_min; // 分 - 取值区间为[0,59] int tm_sec; // 秒 – 取值区间为[0,59] int tm_wday; // 一周中的第几天 – 取值区间为[0,6] int tm_yday; // 一年中的第几天 – 取值区间为[0,365] }; void localtime(unsigned long timestamp, struct tm *t); unsigned long mktime(struct tm *t); #endif
time.c
#include "time.h" static unsigned int mon_yday[2][12] = { { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }, }; static unsigned char isleap(unsigned int year) { return (year%4==0 && year%100!=0) || (year%400==0) ? 1 : 0; } void localtime(unsigned long timestamp, struct tm *t) { unsigned int year = 1970; unsigned char mon = 0; unsigned char leap; unsigned char week = (timestamp%(7*24*3600))/(24*3600)+3; if (week > 6) { week -= 7; } t->tm_wday = week; // 取秒时间 t->tm_sec = timestamp % 60; timestamp /= 60; // 取分钟时间 t->tm_min = timestamp % 60; timestamp /= 60; // 小时数 t->tm_hour = timestamp % 24; timestamp /= 24; // 计算年份 while (1) { if (isleap(year)) { if (timestamp < 366) { break; } timestamp -= 366; } else { if (timestamp < 365) { break; } timestamp -= 365; } year++; } t->tm_year = year-1900; t->tm_yday = timestamp; // 计算月分 leap = isleap(year); for (mon = 0 ; mon < 12 ; mon++) { if (timestamp < mon_yday[leap][mon]) { break; } } mon--; timestamp -= mon_yday[leap][mon]; t->tm_mon = mon; t->tm_mday = timestamp+1; // 日期取值为1到31 } unsigned long mktime(struct tm *t) { unsigned int i = 0; // 以平年时间计算的秒数 unsigned int year = t->tm_year + 1900; unsigned long result = (year - 1970)*365*24*3600 + (mon_yday[isleap(year)][t->tm_mon]+t->tm_mday-1)*24*3600 + t->tm_hour*3600 + t->tm_min*60 + t->tm_sec; // 加上闰年的秒数 for (i = 1970; i < year; i++) { if (isleap(i)) { result += 24 * 3600; } } return result; } /* #include <stdio.h> int main() { // 测试1,时间转时间戳 struct tm t = { 2021 - 1900, 6 - 1, 24, 18, 58, 39 }; time_t timestamp = mktime(&t); printf("timestamp:%u\n", timestamp); // 测试2,时间戳转时间 struct tm t2; localtime(1624536919, &t2); printf("%d %d %d %d %d %d %d %d", t2.tm_year, t2.tm_mon, t2.tm_mday, t2.tm_hour, t2.tm_min, t2.tm_sec, t2.tm_wday, t2.tm_yday); return(0); } */
文章作者:沃航科技