【发布时间】:2023-04-02 08:09:02
【问题描述】:
我正在尝试实现自己的 NTP 客户端。
我可以发送和接收 NTP 消息,我现在需要做的就是将其转换为“实时”时间。我创建了一个函数来执行此操作,但由于某种原因,我得到了正确的所有字段,除了晚 1 天的 day 字段。
我还使用笔、纸和计算器进行了一些快速计算,得到了相同的结果,所以一定有一些我遗漏的东西。
这是我的代码:
void setTime(uint32_t seconds, uint32_t fraction)
{
int yearsPassed = seconds / (60 * 60 * 24 * 365);
year = 1900 + yearsPassed;
int leapYears = yearsPassed / 4;
int secondsLeft = seconds - yearsPassed * 365 * 24 * 60 * 60;
secondsLeft -= leapYears * 60 * 60 * 24;
int daysPassed = secondsLeft / (60 * 60 * 24);
secondsLeft -= daysPassed * 60 * 60 * 24;
int hoursPassed = secondsLeft / (60*60);
secondsLeft -= hoursPassed * 60 * 60;
int minutesPassed = secondsLeft / 60;
secondsLeft -= minutesPassed * 60;
hour = hoursPassed + SUMMERTIME_OFFSET;
minute = minutesPassed;
second = secondsLeft;
us = (fraction * (pow((float)10,(float)6)) / (pow((float)2,(float)32)));
month = getMonth(daysPassed);
day = getDay(month, daysPassed);
}
例如,使用此代码,我可以获取时间 2015/4/28 14:3:15.351731,但日期应该是 29 而不是 28。我最初的想法是我计算的闰年有误,因此错过了 1 天那个,但这似乎是正确的。
编辑
getMonth() 和 getDay() 的代码。它们还没有完全实现,因为我想编写尽可能少的代码来测试它是否有效。
int getMonth(int daysPassed)
{
if (daysPassed < 32)
return 1;
else if (daysPassed < 60)
return 2;
else if (daysPassed < 91)
return 3;
else if (daysPassed < 121)
return 4;
else if (daysPassed < 152)
return 5;
else
return 6;
}
int getDay(int month, int daysPassed)
{
switch (month)
{
case 1:
return daysPassed;
break;
case 2:
return daysPassed - 31;
break;
case 3:
return daysPassed - 59;
break;
case 4:
return daysPassed - 90;
break;
case 5:
return daysPassed - 120;
break;
default:
return 6;
break;
}
}
【问题讨论】:
-
您能打印那里所有变量的值并将其添加到问题中吗?这将节省人们大量计算或重新实现代码的时间。很有可能,您在执行此操作时会自己发现问题。
-
你的
getDay(...)和getMonth(...)是什么样子的(另外,他们为什么不需要知道他们是否在闰年? -
...它们在 1900 年 1 月 1 日是如何工作的?
-
@Roland Shaw 我在尝试让它工作时忽略了当前日期的闰年方面,因为今年不是闰年
-
@AlexNevidomsky 他们如何在 1900 年 1 月 1 日工作?你的意思是如果我将 0 传递给 setTime() 函数?它显示 1900/01/00。这是否意味着您总是必须多加一天?