我正在构建一个嵌入式项目,它在显示器上显示从gps模块检索到的时间,但我也想显示当前日期。我现在有一个unix时间戳,程序是用c编写的。
我正在寻找一种从时间戳计算当前UTC日期的方法,将闰年考虑在内?请记住,这是针对没有fpu的嵌入式项目,因此模拟浮点数学,尽可能避免它的性能要求。
编辑
在看了@r….的代码之后,我决定自己去写这篇文章,并提出了以下建议。

void calcDate(struct tm *tm)
{
  uint32_t seconds, minutes, hours, days, year, month;
  uint32_t dayOfWeek;
  seconds = gpsGetEpoch();

  /* calculate minutes */
  minutes  = seconds / 60;
  seconds -= minutes * 60;
  /* calculate hours */
  hours    = minutes / 60;
  minutes -= hours   * 60;
  /* calculate days */
  days     = hours   / 24;
  hours   -= days    * 24;

  /* Unix time starts in 1970 on a Thursday */
  year      = 1970;
  dayOfWeek = 4;

  while(1)
  {
    bool     leapYear   = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
    uint16_t daysInYear = leapYear ? 366 : 365;
    if (days >= daysInYear)
    {
      dayOfWeek += leapYear ? 2 : 1;
      days      -= daysInYear;
      if (dayOfWeek >= 7)
        dayOfWeek -= 7;
      ++year;
    }
    else
    {
      tm->tm_yday = days;
      dayOfWeek  += days;
      dayOfWeek  %= 7;

      /* calculate the month and day */
      static const uint8_t daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
      for(month = 0; month < 12; ++month)
      {
        uint8_t dim = daysInMonth[month];

        /* add a day to feburary if this is a leap year */
        if (month == 1 && leapYear)
          ++dim;

        if (days >= dim)
          days -= dim;
        else
          break;
      }
      break;
    }
  }

  tm->tm_sec  = seconds;
  tm->tm_min  = minutes;
  tm->tm_hour = hours;
  tm->tm_mday = days + 1;
  tm->tm_mon  = month;
  tm->tm_year = year;
  tm->tm_wday = dayOfWeek;
}

最佳答案

第一次除以86400;余数可以简单地用于得到结果的hh:mm:ss部分。现在,从1970年1月1日起你还有很多日子。然后,我将其调整为自2000年3月1日以来的天数(可能为负数);这是因为2000是闰年周期400的倍数,所以使用除法可以很容易(或至少更容易)计算通过了多少闰年。
与其试图更详细地解释这一点,我将向您介绍我的实现:
http://git.musl-libc.org/cgit/musl/tree/src/time/__secs_to_tm.c?h=v0.9.15

09-11 02:36
查看更多