使用 1990 年 1 月 1 日作为纪元日期将天数转换为 C 中的日期

Posted

技术标签:

【中文标题】使用 1990 年 1 月 1 日作为纪元日期将天数转换为 C 中的日期【英文标题】:convert number of days to a date in C using Jan 1 1990 as an epoch date 【发布时间】:2012-08-25 09:56:30 【问题描述】:

我有一个变量,它表示自 1990 年 1 月 1 日以来的天数。有人知道我该怎么做吗?我正在使用 MCS 8051,所以我不能使用任何脚本、标准库函数或内存分配(malloc 或 calloc)。这也不是家庭作业。任何帮助将不胜感激。

【问题讨论】:

你到底想做什么?系统的纪元是什么,有哪些数值类型可用于算术? 我试图计算自 1990 年 1 月 1 日以来的天数。问题是我正在研究一个架构上旧的嵌入式系统,因此计算不能是计算密集型的。 Michał,感谢您的帮助。我和我的一位同事谈过,经过几次尝试我们弄明白了。 【参考方案1】:

我会给你一个提示:

$ date --date 'jan 1 1990' +%s
631148400

这是 1990 年 1 月 1 日的“纪元日期”;以 Unix 纪元以来的秒数表示。请注意,这只对 POSIX 系统有效。


现在,您已经明确表示没有可用的标准库函数,您可能希望使用预先计算的纪元时间作为开始,并在其中添加 days * 86400

遗憾的是,我猜你不会有足够大的整数类型来处理那个算术。自:

log(633826800, 2) = approx. 29.23951342

您至少需要 32 位类型来保存 Unix 纪元本身的值。

例如,如果您有 32 位 uint32_t 类型,您可以:

uint32_t days_to_epoch_date(int days)

    uint32_t ret = 631148400L; /* value for Jan 1 1990 */
    ret += 86400 * days;
    return ret;

如果您需要使用不同的纪元或比例,值会有所不同,但方法将保持不变。好吧,只要时间度量是线性的。


以下示例对于新信息不再正确,但我将保留它,以防任何能够使用标准库的人都能找到它。

为了使代码具有可移植性,您首先需要在 struct tm 中组装纪元日期:

#include <time.h>

time_t epoch_time_to_time_t(unsigned int days_since_epoch)

    struct tm t = 0;

    t.tm_mday = 1;
    t.tm_mon = 0; /* Jan */
    t.tm_year = 90; /* since 1900 */
    t.tm_isdst = -1;

    /* ... */

那么,如*7.23.2.3所允许的mktime函数:

2 […] 结构的tm_wdaytm_yday 组件的原始值被忽略,其他组件的原始值不限于上述范围。

…在struct tm上加上天数,用mktime()得到最终的time_t

time_t epoch_time_to_time_t(unsigned int days_since_epoch)

    /* ... */

    t.tm_mday += days_since_epoch;

    return mktime(&t);

【讨论】:

感谢您的提示,但我不能使用标准库和函数,例如 time.h 和 mktime。一切都必须在内部制作。 那么我认为您需要使用某种预先计算的无符号整数作为初始值(相对于时代)并对其进行算术运算。不过,我不确定您是否会有足够大的整数类型。 @InternetSeriousBusiness:我相信他根本没有标准库。只有一些极简的 C 交叉编译器。 您是在回答“使用 1990 年作为纪元进行转换”,还是“转换为 Unix 纪元 time_t 值”? @aschepler:嗯,我从详细的描述判断,1990 是指天数变量,Unix epoch time_t 是目标格式。因此,我以该值为例;然而,答案实际上可以推广到任何其他假设线性时间表示的时代。【参考方案2】:

有一本书收集了大量的日期和时间计算细节和算法,这几乎肯定值得一读。标准 C 中的源代码支持它(可能是 C89,当然不是更新的)。

Standard C Date/Time Library: Programming the World's Calendars and Clocks Lance Latham,CMP,1998 年,ISBN 978-0879304966。

如果您需要从头开始使用日期算术,这将是一个很好的资源,因为日历中充满了容易错过的特殊情况。

【讨论】:

感谢您的链接。它看起来像一本非常好的书。遗憾的是,该代码已获得许可,未经作者许可不得公开使用。如果我有时间,我一定会尝试购买它或类似的东西。出于某种原因,我什至没有想到可能有关于这个主题的书籍。再次感谢。 我记得,我最初是通过浏览实体书店的编程部分找到的,当时有这样的东西。 (褪色的价格标签仍然贴在我的副本上,上面写着“Vroman's Pasadena”,它仍然存在并且是一家很棒的书店。)我不知道我需要一本关于日期算术的书,但我很高兴它是架子上的参考。我建议联系以询问现在适用哪些许可条款,但还要注意我的副本中的 URL 现在指向 404 页面。

以上是关于使用 1990 年 1 月 1 日作为纪元日期将天数转换为 C 中的日期的主要内容,如果未能解决你的问题,请参考以下文章

Bailian3860 unix纪元日期时间

Bailian3860 unix纪元日期时间

检查字符串是否有日期,任何格式

Pandas groupby 多列基础日期列按纪元周

使用 strftime 将 python 日期时间转换为纪元

std::chrono:将时钟的纪元设置为 1/1/0000