我有一个嵌入式系统,目前使用由钟表晶体驱动的实时时钟跟踪事件应该发生的秒数。
现在需要跟踪实际的日期和时间。因此,我需要能够从开始日期/时间和以秒为单位的偏移量计算日,月,年,小时,分钟和秒。
考虑到闰年,夏令时(DST)和其他并发症,有没有人能指出我正确的方向?
硬件解决方案不是一种选择,因为此功能已添加到现有产品中。 RTC外设集成在为下一代器件选择的MCU中。
答案 0 :(得分:1)
日历代码可能有点复杂 - 如果您使用的C运行时库没有内置的支持(以及将时钟计数器集成到它的某种方式),您可以考虑查看{中的代码{3}}并根据您的需求进行调整。
答案 1 :(得分:1)
C Snippets archive有一些date and time functions。 更新:不幸的是,C片段存档现已不存在了。我已更新链接以指向该页面的Web存档。
另请参阅“Julian day”,Wikipedia,其中包含Julian date calculation的公式。
如果您想进一步搜索,“julian date calculation”Google搜索应该会发现更多。
答案 2 :(得分:1)
我很无聊,无法抗拒尝试解决方案。这是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的开始日期和结束日期之间的检查,并相应地调整小时。
答案 3 :(得分:0)
以下函数确定给定年份是否为闰年:
bool is_leap_year(int year)
{
return ((0 == year % 400) || ((0 == year % 4) && (0 != year % 100)));
}