Получение смещения на 1 день при конвертации времени 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;
}
}

0

Решение

У вас есть ошибка в заборе daysPastкак это завершено дней, а не количество частичный дней.

Рассмотрим ввод в 1 секунду (черт, лучше, сделайте это модульным тестом), который должен разрешиться до 01.01.1900 00:00:01 — это даст daysPast как 0, который является числом прошедших дней, он не учитывает текущий день.

Конечно, вам также нужно учитывать, является ли текущий год високосным, при расчете дня в году; и для полноты, и для совместимости в 2100 году ваш алгоритм високосных лет — наивно.

1

Другие решения


По вопросам рекламы [email protected]