我正在构建一个嵌入式项目,该项目显示从显示器上的GPS模块中检索的时间,但我也想显示当前日期。我目前有时间作为unix时间戳,并且该项目用C语言编写。将unix时间戳转换为不带系统库的日期
我正在寻找一种方法来计算从时间戳中计算当前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, 30, 31, 31, 30, 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;
}
闰秒呢? – wonce
只有当他们的计算不存在会导致大的误差(我怀疑)。 – Geoffrey
由于闰秒,UTC和GPS时间现在有16秒不同。这不会很快变化。换句话说,如果你只是显示当前日期,你可以忽略闰秒。 – kmort