在将NTP时间转换为日期时获得抵消1天

时间:2015-04-29 12:06:59

标签: c++ math time ntp

我正在尝试实施自己的NTP客户端。

我可以发送和接收NTP消息,我现在需要做的是将其转换为"真实"时间。我已经创建了一个函数来执行此操作,但由于某种原因,我得到了所有字段都正确,除了1天后的日期字段。

我还用笔,纸和计算器进行了一些快速计算,我得到了相同的结果,因此必须有一些我不知道的东西。

这是我的代码:

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;
    }
}

1 个答案:

答案 0 :(得分:1)

您的daysPast上有一个fencepost错误,因为它是已完成的天,而不是部分天的数量。< / p>

考虑1秒的输入(哎呀,更好的是,让它成为单元测试),它应该解析为1/1/1900 00:00:01 - 它会将你的daysPast设为0,同时是过去的天数,它并不代表当天。

当然,您还需要考虑当年是否计算一年中的闰年;为了完整性,并且在2100年的兼容性,你的算法闰年是一个天真的。