【问题标题】:References for implementing calendar functionality in an embedded system?在嵌入式系统中实现日历功能的参考?
【发布时间】:2009-12-01 14:54:56
【问题描述】:

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

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

谁能指出我考虑闰年、夏令时 (DST) 和其他并发症的正确方向?


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

【问题讨论】:

  • 为什么不在设计中添加 RTC 电路?或者在这种情况下可能不是一个选项?
  • 我认为我不需要添加另一个 IC 就可以将一个纪元以来的秒数转换为日期/时间......
  • 许多微控制器都具有片上 RTC,如果需要,也许您可​​以使用一个?

标签: c datetime embedded calendar


【解决方案1】:

C Snippets archive 有一些 date and time functions更新:不幸的是,C sn-ps 存档现已失效。我已更新链接以指向该页面的网络存档。

另请参阅“Julian day”、Wikipedia,其中包括 Julian date calculation 的公式。

如果您想进一步搜索,“julian date calculation”Google 搜索应该会发现更多信息。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我很无聊,忍不住尝试解决方案。这是 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 的开始和结束日期之间的检查应该很容易,并相应地调整小时。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-23
          • 2011-03-16
          • 1970-01-01
          • 2014-06-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多