我正在尝试在 C 中实现两个简单的转换器,日期/时间到时间戳,反之亦然,不依赖于时间库例程(例如 localtime、mktime 等,主要是因为其中一些是线程-不安全)。
我之前在将日期/时间转换为时间戳和反之亦然下发布了一个类似的问题,现在想再次提交它并进行一些显着的更改:
我有以下日期/时间结构:
typedef struct
{
unsigned char second; // 0-59
unsigned char minute; // 0-59
unsigned char hour; // 0-59
unsigned char day; // 1-31
unsigned char month; // 1-12
unsigned char year; // 0-99 (representing 2000-2099)
}
date_time_t;
我想对以下转换例程有第二意见(给定合法输入):
static unsigned short days[4][12] =
{
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335},
{ 366, 397, 425, 456, 486, 517, 547, 578, 609, 639, 670, 700},
{ 731, 762, 790, 821, 851, 882, 912, 943, 974,1004,1035,1065},
{1096,1127,1155,1186,1216,1247,1277,1308,1339,1369,1400,1430},
};
unsigned int date_time_to_epoch(date_time_t* date_time)
{
unsigned int second = date_time->second; // 0-59
unsigned int minute = date_time->minute; // 0-59
unsigned int hour = date_time->hour; // 0-23
unsigned int day = date_time->day-1; // 0-30
unsigned int month = date_time->month-1; // 0-11
unsigned int year = date_time->year; // 0-99
return (((year/4*(365*4+1)+days[year%4][month]+day)*24+hour)*60+minute)*60+second;
}
void epoch_to_date_time(date_time_t* date_time,unsigned int epoch)
{
date_time->second = epoch%60; epoch /= 60;
date_time->minute = epoch%60; epoch /= 60;
date_time->hour = epoch%24; epoch /= 24;
unsigned int years = epoch/(365*4+1)*4; epoch %= 365*4+1;
unsigned int year;
for (year=3; year>0; year--)
{
if (epoch >= days[year][0])
break;
}
unsigned int month;
for (month=11; month>0; month--)
{
if (epoch >= days[year][month])
break;
}
date_time->year = years+year;
date_time->month = month+1;
date_time->day = epoch-days[year][month]+1;
}
我已经根据大量的法律意见(从 01/01/2000 到 31/12/2099 之间)对此进行了测试。任何建设性的意见将不胜感激(性能改进建议,可读性等)......
更新 - 我在这里的最终目标(由于我发布这个问题):
我有一个 STM32(基于 ARM 的皮层),其定时器配置为每 10 毫秒中断一次 CPU。此外,我连接了一个 RTC,可以从中读取日期/时间(分辨率为 1 秒)。访问 RTC 效率较低,因此我只想读取一次,然后使用 10ms 定时器中断计算日期/时间。我希望避免使用“本地时间”,因为我必须使用互斥锁来保护它。想到的唯一解决方案是实现我自己的“本地时间”,以及作为后续结果 - 我自己的“mktime”(我在上面代码中的时代从 2000 年初开始计算秒数)。