Рекомендации по реализации функций календаря во встроенной системе? - PullRequest
3 голосов
/ 01 декабря 2009

У меня есть встроенная система, которая в настоящее время отслеживает секунды, пока событие не должно произойти, используя часы реального времени, управляемые часовым кристаллом.

Теперь необходимо отслеживать фактическую дату и время. Итак, мне нужно иметь возможность рассчитать день, месяц, год, час, минуту и ​​секунду из начальной даты / времени и смещения в секундах.

Может ли кто-нибудь указать мне правильное направление для учета високосных годов, перехода на летнее время и других осложнений?


Аппаратные решения не являются опцией, так как эта функция добавляется в существующий продукт. Периферийное устройство RTC интегрировано в MCU, выбранный для устройства следующего поколения.

Ответы [ 4 ]

1 голос
/ 02 декабря 2009

Мне скучно, я не могу устоять перед попыткой решения. Вот прототип на ruby ​​- должно быть достаточно ясно, чтобы перевести на C.

Дано offset и дата начала сохранена как: Baseyear, Baseday, Basesec, где день 0 = 1 января, Вы можете рассчитать дату как

#initialize outputs
year= Baseyear
day = Baseday
sec = Basesec+offset

#days & seconds remaining in the current year
is_leap = is_leap_year(year)
days_remaining = 365+(is_leap ? 1 : 0) - day
secs_remaining = SEC_PER_DAY*days_remaining

#advance by year
while (sec>=secs_remaining)
  sec-=secs_remaining
  year+=1
  is_leap = is_leap_year(year)
  days_remaining = 365+(is_leap ? 1 : 0)
  secs_remaining = SEC_PER_DAY*days_remaining
  day=0 
end

#sec holds seconds into the current year, split into days+seconds
day += sec / SEC_PER_DAY
day = day.to_i #cast to int
sec %= SEC_PER_DAY

#lookup month
for i in (0..11)
  dpm = DAYS_PER_MONTH[i] # =[31,28,31,30,...]
  if (i==1 && is_leap) 
   dpm+=1
  end
  if day < dpm
   month = i
   break
  else
    day-=dpm
  end
end

day+=1 #1-based
hour = sec/3600
min = (sec%3600)/60
sec = sec%60
puts "%s %d, %d @ %02d:%02d:%02d" % [MONTHNAME[month],day,year, hour, min, sec]

Должно быть легко добавить проверку того, что день находится между начальным и конечным днями летнего времени в текущей локали, и соответствующим образом скорректировать час.

1 голос
/ 01 декабря 2009

Код календаря может быть немного сложным - если используемая вами библиотека времени выполнения C не имеет такой встроенной поддержки (и некоторого способа интегрировать в нее ваш счетчик часов), вы можете рассмотреть код в PJ Plauger's «Стандартная библиотека C» и адаптация к вашим потребностям.

1 голос
/ 01 декабря 2009

Архив C Snippets имеет некоторые функции даты и времени . Обновление: к сожалению, архив фрагментов C теперь не существует. Я обновил ссылку, указав на веб-архив страницы.

См. Также « Юлианский день », Википедия , которая включает формулы для Юлианская дата расчета .

A " вычисление юлианской даты " Поиск Google должен найти больше, если вы хотите искать дальше.

0 голосов
/ 01 декабря 2009

Следующая функция определяет, является ли данный год високосным:

bool is_leap_year(int year)
{
    return ((0 == year % 400) || ((0 == year % 4) && (0 != year % 100)));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...