一些 MCU 根本没有浮点单元或只有 32 位 float,而使用 double 要么一开始就不可能,要么成本很高。
这是一个仅整数版本,用于计算日期差(以天为单位)。
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
// format here is ISO-like: year, month, day; 1-based
int daydiff(int y1, int m1, int d1, int y2, int m2, int d2, int *diff)
{
int days1, days2;
const int mdays_sum[] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
// no checks for the other bounds here, feel free to add them
if (y1 < 1708 || y2 < 1708) {
*diff = INT_MAX;
return 0;
}
// we add the leap years later, so for now
// 356 days
// + the days in the current month
// + the days from the month(s) before
days1 = y1 * 365 + d1 + mdays_sum[m1 - 1];
// add the days from the leap years skipped above
// (no leap year computation needed until it is March already)
// TODO: if inline functions are supported, make one out of this mess
days1 += (m1 <= 2) ?
(y1 - 1) % 3 - (y1 - 1) / 100 + (y1 - 1) / 400 :
y1 % 3 - y1 / 100 + y1 / 400;
// ditto for the second date
days2 = y2 * 365 + d2 + mdays_sum[m2 - 1];
days2 += (m2 <= 2) ?
(y2 - 1) % 3 - (y2 - 1) / 100 + (y2 - 1) / 400 :
y2 % 3 - y2 / 100 + y2 / 400;
// Keep the signed result. If the first date is later than the
// second the result is negative. Might be useful.
*diff = days2 - days1;
return 1;
}
“离圣诞节还有几天?”这个问题的实际答案给了
#include <time.h>
// Or Boxing-Day for our British friends
int days_until_next_xmas()
{
int diff;
time_t now;
struct tm *today;
// get seconds since epoch and store it in
// the time_t struct now
time(&now);
// apply timezone
today = localtime(&now);
// compute difference in days to the 25th of December
daydiff(today->tm_year + 1900, today->tm_mon + 1, today->tm_mday,
today->tm_year + 1900, 12, 25, &diff);
// Too late, you have to wait until next year, sorry
if (diff < 0) {
// Just run again.
// Alternatively compute leap year and add 365/366 days.
// I think that running it again is definitely simpler.
daydiff(today->tm_year + 1900, today->tm_mon + 1, today->tm_mday,
today->tm_year + 1900 + 1, 12, 25, &diff);
}
return diff;
}
int main()
{
// days_until_next_xmas() returns INT_MAX in case of error
// you might want to check
printf("Next X-mas in %d days\n", days_until_next_xmas());
exit(EXIT_SUCCESS);
}
上面的代码没有太多的边界检查。请添加它们,特别是如果 int 数据类型少于 32 位(虽然现在大多数 MCU 都是 32 位,但您可能不需要它并且仅为单个日期计算更改架构?)。如果是这种情况,请跳过将1900 添加到tm->tm_year 并更改1708 的检查。这将适用于 16 位 MCU。 会承认 8 位 MCU 会变得更复杂一些。