【问题标题】:Converting days since Jan.1 1900 to today's date将自 1900 年 1 月 1 日以来的天数转换为今天的日期
【发布时间】:2014-11-07 00:43:28
【问题描述】:
typedef struct dbdatetime
{                       // Internal representation of DATETIME data type
LONG  dtdays;       // No of days since Jan-1-1900 (maybe negative)
ULONG dttime;       // No. of 300 hundredths of a second since midnight
} DBDATETIME;

我正在尝试将此结构转换为今天的日期。我不怀疑时间会给我带来很多麻烦,但我在将总天数转换为正确的月份和日期的逻辑上遇到了问题。

例如。 11 月 7 日星期五是 41948 天。

您可以除以 365.2425+1900 来获得当前年份,但如何获得正确的月份/日期。

C 有内置的东西来处理这个吗?我不是专业的 C 程序员。

【问题讨论】:

  • 您绝对不想手动执行此操作。正确处理非常棘手,并且有很多边缘情况。我不记得要调用的库函数,但这是你需要做的。
  • 如果您想推出自己的代码 - 一项有趣的任务 - 假设今年在二月结束。 (它曾经在大约 2000 年前的 2 月结束。_Octo_ber 是第 8 个月,_Dece_mber 是第 10 个月。)然后闰日是在年底。建议从 2000 年 3 月 1 日起计算

标签: c date datetime logic


【解决方案1】:

C 标准中没有任何内容可以直接处理此问题,但如果您愿意编写特定于操作系统的代码,或者可以导入像 boost::date_time 这样的库,这是最好的选择。不要试图自己处理它,除非你可以接受边缘情况是错误的。众所周知,日期和时间很难弄对。

这里是 date_time 的文档,它可以对日期进行算术运算,包括“将 N 天添加到 1/1/1900”。 http://www.boost.org/doc/libs/1_56_0/doc/html/date_time/gregorian.html#date_time.gregorian.date_duration

date d(1900, Jan, 1)
d += days(dtdays);

编辑: OP 不能使用 boost,但我会留在这里,以防未来的访问者可以使用该信息。

【讨论】:

  • “C 标准中没有任何东西可以处理这个”?你的意思是喜欢mktime 和朋友?
  • 至于boost,问题标记为C。
  • mktime 返回一个time_t,它(a)是实现定义了它是如何工作的,并且(b)在常见的实现中是自 1970 年以来的秒数。我不知道你会如何实际实现他的请求使用它。
  • 你说得对,如果C++受到限制,他就不能使用boost,但他并没有具体说C++是不允许的。一般来说,在其他纯 C 代码库中使用 boost 应该很容易。只需将其保存在自己的编译单元中即可。
【解决方案2】:

正如您所说,您可以将天数除以 365.2425 以获得一年的大致估计值。一旦你有了它,使用 1900 年和那一年之间的年数和闰年来计算到那一年的天数。

您需要确保检测闰年的逻辑是正确的。一旦你知道哪些年份是闰年,你会没事的。例如,1900 年不是闰年,即使它可以被 4 整除。谷歌闰年规则可以找出原因。

一旦你有了它,剩余的天数将属于当前年份。再次使用闰年逻辑来确定您当前的年份是否是闰年。然后,只需计算每个月的天数。

【讨论】:

    【解决方案3】:

    C++ 是不可能的,感谢所有输入的家伙。

    我确实找到了这个算法,到目前为止似乎有效,但现在正在测试它。

    int l = nSerialDate + 68569 + 2415019;
    int n = int(( 4 * l ) / 146097);
            l = l - int(( 146097 * n + 3 ) / 4);
    int i = int(( 4000 * ( l + 1 ) ) / 1461001);
        l = l - int(( 1461 * i ) / 4) + 31;
    int j = int(( 80 * l ) / 2447);
     nDay = l - int(( 2447 * j ) / 80);
        l = int(j / 11);
        nMonth = j + 2 - ( 12 * l );
    nYear = 100 * ( n - 49 ) + i + l;
    

    现在正试图找到它背后的一些理论。

    【讨论】:

    • 是的,这个算法很接近,但似乎不能完全工作。 41948 正在返回:2014 年 11 月 5 日而不是 2014 年 11 月 7 日
    • 顺便说一句:如果您选择使用 MS Excel 来检查您的工作笔记 2 件事:1) 1900 年 1 月 1 日是第 1 天(不是 1 月 1 日以来的天数, 1900) 和 2) 根据 Excel 1900 年 2 月 29 日存在(他们拒绝修复代码中的错误。)
    • 这基本上会在 1 天之内把所有东西都扔掉,对吗?我做了一些阅读,这显然与希望能够导入 Lotus 1 2 3 文件有关。
    【解决方案4】:

    感谢大家的所有投入,这就是我最终要做的。

    1. 将 dtdays 转换为秒,减去 Jan-1-1900(序列日期)和 Jan-1-1970(UNIX 时间)之间的秒数偏移量。即 2208988800,这给我们留下了 UNIX 时间。
    2. 将百分之一秒转换为秒并添加到总数中。
    3. 使用 gmtime() 将 UNIX 时间转换为 tm 结构。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-09
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      相关资源
      最近更新 更多