【问题标题】:How to convert in modern C++ a double into a datetime如何在现代 C++ 中将双精度转换为日期时间
【发布时间】:2017-10-01 20:13:38
【问题描述】:

在导出 Excel 工作表时生成双精度时,如何使用 date.h 库在现代 C++ (C++11/14/17) 中将 double 转换为日期时间作为 CSV 文件?

例如,Excel中出现的日期时间:

21/08/2017 11:54

已被 Excel 转换为 CSV 文件作为双精度:

42968.4958333333

谢谢。

2019 年 7 月 11 日编辑:这个问题是关于 date.h 库的使用。指出为“可能重复”的其他问题不需要使用此库(另请参阅 date.h 库作者的以下评论)

【问题讨论】:

  • 取决于Excel决定如何将数据转换为double,如果你能提供它会更容易帮助你。
  • 如果你使用MFC/ATL,有一个非常方便的COleDateTime class,它有一个构造函数,它采用这种格式的double
  • pastebin.com/XCmUzfuM 我认为.. 与DateTime Java 和 C# 等其他语言中的类相比,std::chrono 仍然有点不文明..
  • 这个问题不可能与date time conversion 重复,因为这个问题询问如何使用date.h 库。当问到另一个问题时,这个库甚至都不存在。也没有更新其他问题来询问这个较新的库。

标签: c++ excel c++20 excel-dates


【解决方案1】:

使用date.h,它可能看起来像这样:

#include "date/date.h"
#include <iostream>

std::chrono::system_clock::time_point
to_chrono_time_point(double d)
{
    using namespace std::chrono;
    using namespace date;
    using ddays = duration<double, days::period>;
    return sys_days{December/30/1899} + round<system_clock::duration>(ddays{d});
}

int
main()
{
    using date::operator<<;
    std::cout << to_chrono_time_point(42968.495833333333333333333) << '\n';
}

哪个输出:

2017-08-21 11:54:00.000000

此定义假定您从 42968.4958333333 到 21/08/2017 11:54 的映射是正确的。我在另一个地方看到时代应该是 1899-12-31,而不是 1899-12-30。无论如何,一旦找到正确的纪元,这就是执行计算的方式。

啊,https://en.wikipedia.org/wiki/Leap_year_bug 解释了一个错误。为了向后兼容 Lotus 1-2-3,Excel 的作者故意将 1900 年视为闰年。

此输出是在 macOS 上生成的,其中 system_clock::durationmicroseconds。在system_clock::duration 有其他单位的其他平台上,输出会略有不同。

另外:在这个范围内,IEEE 64 位 double 的精度比 nanoseconds 粗,但比 microseconds 更精细(大约是 microsecond 的一半)。

【讨论】:

  • 霍华德:再次感谢您的回答。非常感谢您对 date.h 库的支持。
猜你喜欢
  • 2014-04-24
  • 1970-01-01
  • 2020-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多