代码之家  ›  专栏  ›  技术社区  ›  Judge Maygarden

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

  •  3
  • Judge Maygarden  · 技术社区  · 16 年前

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

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

    考虑到闰年、夏令时(DST)和其他复杂因素,有人能给我指出正确的方向吗?


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

    4 回复  |  直到 16 年前
        1
  •  1
  •   Michael Burr    16 年前

    日历代码可能有点复杂——如果你正在使用的C运行库没有内置的支持(和某种方式将时钟计数器集成到它),你可能会考虑查看代码。 P.J. Plauger's "The Standard C Library"

        2
  •  1
  •   AShelly    16 年前

    我很无聊,忍不住尝试解决办法。这是一个ruby原型——应该足够清晰,可以翻译成C。

    鉴于 offset Baseyear, Baseday, Basesec 其中第0天=1月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]
    

    在当前区域设置中,应该可以轻松地添加一个检查,确保日期介于DST的开始日期和结束日期之间,并相应地调整小时数。

        3
  •  1
  •   Craig McQueen Dr. Watson    13 年前

    这个 C Snippets archive date and time functions . 更新:不幸的是,C代码片段存档现在已经失效。我已经更新了链接,指向网页的web存档。

    另见“ Julian day Wikipedia ,其中包括 Julian date calculation .

    A“ julian date calculation

        4
  •  0
  •   Judge Maygarden    16 年前

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

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