【问题标题】:Convert date/time to time-stamp and vice versa将日期/时间转换为时间戳,反之亦然
【发布时间】:2013-11-03 18:33:17
【问题描述】:

我试图在 C 中实现两个简单的转换器,日期/时间到时间戳,反之亦然,不依赖于时间库例程,例如 mktime 等。

时间戳以秒为单位,日期/时间结构格式如下:

  • 无符号字符年份:0 到 99(表示范围 2000 到 2099)

  • 无符号字符月份:1 到 12

  • 无符号字符日:1 到 31

  • 无符号字符小时:0 到 23

  • 无符号字符分钟:0 到 59

  • 无符号字符秒:0 到 59

我想对 dt2ts 转换器有第二个意见(假设输入是合法的):

unsigned int dt2ts(const dt_t* dt)
{
    static unsigned short days[] = {0,31,59,90,120,151,181,212,243,273,304,334};
    return ((((dt->year*365+dt->year/4)+days[dt->month-1]+dt->day)*24+dt->hour)*60+dt->minute)*60+dt->second;
}

除此之外,我将不胜感激完成 ts2dt 转换器的一些帮助:

void ts2dt(unsigned int ts,dt_t* dt)
{
    dt->second = ts%60; ts /= 60;
    dt->minute = ts%60; ts /= 60;
    dt->hour   = ts%24; ts /= 24;
    dt->day    = ?????;
    dt->month  = ?????;
    dt->year   = ?????;
}

谢谢

【问题讨论】:

  • 希望这是一个练习,而您不仅仅是在创建 Y2100 错误。 :-) 你关心夏令时吗?当有 2 月 29 日时,您肯定需要考虑闰年。
  • 你为什么要把所有的代码放在一行?它不是 Perl 或 Python。这种“风格”真的很难读。
  • 可能想要将const 设为数组static unsigned short days[]
  • (dt->year*365+dt->year/4)+days[dt->month-1] 不正确,因为它没有正确考虑闰日。

标签: c datetime timestamp


【解决方案1】:

OP 已准备好处理小时、分钟、秒。对 Y、M、D 有一点帮助。

注意:从 2000 年 1 月 1 日到 2099 年 12 月 31 日的天数至少需要一个 16 位整数。即使unsigned 是 2 个字节,以下操作也应该有效。

unsigned DivRem(unsigned Dividend, unsigned Divisor, unsigned *Remainder) {
  unsigned Quotient = Dividend/Divisor;
  *Remainder = Dividend - Quotient*Divisor;
  return Quotient;
}

void Day2000ToYMD(unsigned DaySince2000Jan1, unsigned *Y, unsigned *M, unsigned *D) {
  unsigned OlympiadDay;  // Every 4 years is an Olympiad
  *Y = 4*DivRem(DaySince2000Jan1, 365*4+1, &OlympiadDay);
  *D = 1;
  if (OlympiadDay >= (31+29-1)) {  // deal with Feb 29th and after
    OlympiadDay--;
    if (OlympiadDay == (31+29-1)) {
      (*D)++;
    }
  }
  unsigned YearDay;      // Day of the year 0 to 364
  *Y += DivRem(OlympiadDay, 365, &YearDay);
  static const unsigned short days[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
  *M = 1;
  while (days[*M] <= YearDay) (*M)++;
  *D += YearDay - days[*M - 1];
}

[编辑] 提供的答案试图将年份的概念保持为 1 月 1 日至 12 月 31 日。由于此答案不需要需要处理大约 100 年和 400 年的闰年,我一直保持这种风格。

一般来说,一旦添加了这 2 条规则,如果将年初改为 3 月 1 日并于 2 月 28 日结束,计算就会变得更容易。 FWIW,这对儒略历/公历古代发展的更一致的看法。因此 *Oct*ober 是第 8 个月,*Dec*ember 是第 10 个月。

【讨论】:

    猜你喜欢
    • 2012-01-18
    • 2021-08-31
    • 2013-01-30
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    相关资源
    最近更新 更多