我正在构建一个嵌入式项目,显示从显示器上的GPS模块检索的时间,但我还想显示当前日期.我目前有时间作为unix时间戳,而progject是用C语言编写的.
我正在寻找一种从时间戳计算当前UTC日期的方法,考虑到闰年?请记住,这是针对没有FPU的嵌入式项目,因此模拟浮点数学,尽可能避免性能.
编辑
在看了@R …的代码之后,我决定自己写一篇文章并提出以下内容.
void calcDate(struct tm *tm) { uint32_t seconds,minutes,hours,days,year,month; uint32_t dayOfWeek; seconds = gpsGetEpoch(); /* calculate minutes */ minutes = seconds / 60; seconds -= minutes * 60; /* calculate hours */ hours = minutes / 60; minutes -= hours * 60; /* calculate days */ days = hours / 24; hours -= days * 24; /* Unix time starts in 1970 on a Thursday */ year = 1970; dayOfWeek = 4; while(1) { bool leapYear = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); uint16_t daysInYear = leapYear ? 366 : 365; if (days >= daysInYear) { dayOfWeek += leapYear ? 2 : 1; days -= daysInYear; if (dayOfWeek >= 7) dayOfWeek -= 7; ++year; } else { tm->tm_yday = days; dayOfWeek += days; dayOfWeek %= 7; /* calculate the month and day */ static const uint8_t daysInMonth[12] = {31,28,31,30,31}; for(month = 0; month < 12; ++month) { uint8_t dim = daysInMonth[month]; /* add a day to feburary if this is a leap year */ if (month == 1 && leapYear) ++dim; if (days >= dim) days -= dim; else break; } break; } } tm->tm_sec = seconds; tm->tm_min = minutes; tm->tm_hour = hours; tm->tm_mday = days + 1; tm->tm_mon = month; tm->tm_year = year; tm->tm_wday = dayOfWeek; }
首先除以86400;剩下的部分可以用来获得结果的HH:MM:SS部分.现在,你自1970年1月1日起离开了很多天.然后,我将把它作为一个常数调整为自2000年3月1日以来的天数(可能是负数);这是因为2000年是闰年周期的400的倍数,这使得计算使用除法已经过了多少闰年变得容易(或者至少更容易).
我将向您介绍我的实现,而不是试图更详细地解释这一点:
http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c?h=v0.9.15