在嵌入式系统中实现日历功能的参考?

发布于 2024-08-12 13:56:24 字数 243 浏览 2 评论 0原文

我有一个嵌入式系统,目前可以使用由手表晶体驱动的实时时钟来跟踪秒数,直到事件发生为止。

现在它需要跟踪实际的日期和时间。因此,我需要能够从开始日期/时间和以秒为单位的偏移量计算日、月、年、小时、分钟和秒。

谁能给我指明正确的方向,以考虑闰年、夏令时 (DST) 和其他复杂情况?


硬件解决方案不是一种选择,因为此功能正在添加到现有产品中。 RTC 外设已集成到为下一代设备选择的 MCU 中。

I have an embedded system that currently keeps track of seconds until an event is supposed to occur using a real-time clock driven by a watch crystal.

Now it needs to keep track of the actual date and time. So, I need to be able to calculate the day, month, year, hour, minute and second from a start date/time and offset in seconds.

Could anyone point me in the right direction for taking into account leap years, daylight savings time (DST) and other complications?


Hardware solutions are not an option as this feature is being added to an existing product. An RTC peripheral is integrated into the MCU chosen for the next generation device.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

初见终念 2024-08-19 13:56:24

C Snippets archive 有一些 日期和时间函数更新:不幸的是,C 代码片段存档现已失效。我已更新链接以指向该页面的网络存档。

另请参阅“儒略日", 维基百科,其中包含 儒略日期计算

如果您愿意,“朱利安日期计算”Google 搜索应该会发现更多信息进一步搜索。

The C Snippets archive has some date and time functions. Update: unfortunately, the C snippets archive is now defunct. I have updated the link to point to the web archive of the page.

See also "Julian day", Wikipedia, which includes formulas for Julian date calculation.

A "julian date calculation" Google search should uncover more if you want to search further.

往事随风而去 2024-08-19 13:56:24

日历代码可能有点复杂 - 如果您使用的 C 运行时库没有内置此类支持(以及某种将时钟计数器集成到其中的方法),您可能会考虑查看 PJ Plauger 的“标准 C 库” 并根据您的需要进行调整。

Calendar code can be a bit complex - if the C runtime library you're using doesn't have such support built-in (and some way to integrate your clock counter to it) you might consider looking at the code in P.J. Plauger's "The Standard C Library" and adapting it to your needs.

铁轨上的流浪者 2024-08-19 13:56:24

我很无聊,忍不住尝试解决方案。这是 ruby​​ 中的原型 - 应该足够清晰,可以翻译为 C。

给定 offset 和存储为的开始日期:Baseyear, Baseday, Basesec 其中第 0 天 = Jan1,
您可以计算日期,因为

#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]

添加一个检查应该很容易,以确保该天位于当前区域设置中 DST 的开始日和结束日之间,并相应地调整小时。

I'm bored, couldn't resist trying a solution. Here's a prototype in ruby - should be clear enough to translate to C.

Given offset and a start date stored as: Baseyear, Baseday, Basesec where day 0 = Jan1,
you can calculate the date as

#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]

It should be easy to add a check that the day is between the begin and end days for DST in the current locale, and adjust the hour accordingly.

宫墨修音 2024-08-19 13:56:24

以下函数确定给定年份是否为闰年:

bool is_leap_year(int year)
{
    return ((0 == year % 400) || ((0 == year % 4) && (0 != year % 100)));
}

The following function determines whether a given year is a leap year:

bool is_leap_year(int year)
{
    return ((0 == year % 400) || ((0 == year % 4) && (0 != year % 100)));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文