将(纪元)时间从 C++ 发送到 Javascript

Mar*_*tar 1 c++ export epoch c++20

假设我有以下程序将对象导出为 JSON:

\n
struct MyChronoObject {\n  std::string name;\n  std::chrono::system_clock::time_point birthday;\n\n  MyChronoObject(const std::string name_) : name(name_) {\n    birthday = std::chrono::system_clock::now();\n  }\n\n  std::string toJSON1() {\n    std::string s = "{ \\"name\\": \\"" + name + "\\", \\"birthday\\": ";\n    s += std::to_string((birthday.time_since_epoch().count() / 1000000));\n    s += " }";\n    return s;\n  }\n\n  std::string toJSON2() {\n    std::string s = "{ \\"name\\": \\"" + name + "\\", \\"birthday\\": ";\n    s += std::to_string((birthday.time_since_epoch().count()));\n    s += " }";\n    return s;\n  }\n\n  void setBirthday(int birthday_in_seconds) {\n    // how do I properly cast this?\n  }\n};\n
Run Code Online (Sandbox Code Playgroud)\n

其中,对于toJSON1(),有输出{ "name": "Steve", "birthday": 16687719115 }

\n

这段代码有几个问题(我会提到,但可能会在单独的线程中解决它们),但首先也是最重要的......

\n
    \n
  • 号码16687747280不正确。如果我这样做的话,它应该短一位数seconds或长两位数: EpochConvertermilliseconds
  • \n
  • 不将生日除以一百万,toJSON2(), 会导致一个数字对于 : 来说太长,而对于:microseconds来说太短 2 位数字。nanoseconds16687747280849928
  • \n
\n

那么哪种方式是正确的(也是最有效的)来存储和转换存储的纪元时间,以便我可以将其导出到 Javascript 可以使用的东西?

\n

预先感谢您!\n\xc2\xa0

\n
\n

PS:我还有其他问题:

\n
    \n
  • 如何回传程序C++从前端接收到的数字(如setBirthday)?
  • \n
  • chrono如果秒足够的话,我是否应该将日期存储为对象?
  • \n
  • 如何精确添加一年,以便我在同一日期着陆(例如 25.1.20 19到 25.1.20 20),考虑到闰年等因素)。
  • \n
  • 1970 年之前的日期怎么样?
  • \n
\n

Ran*_*tep 6

请注意, 的默认单位std::chrono::system_clock未定义。birthday.time_since_epoch().count() / 1000000您应该将时间单位转换为适合您的单位,而不是使用:

\n
std::chrono::duration_cast<std::chrono::seconds>(birthday.time_since_epoch())\n    .count()\n
Run Code Online (Sandbox Code Playgroud)\n

这将为您提供秒数。

\n

您还可以使用std::chrono::ceil<seconds>, std::chrono::floor<seconds>,std::chrono::round<seconds>来表示不同的舍入模式。

\n
\n
    \n
  • 要将整数转换回 a time_point,您可以执行以下操作:
  • \n
\n
std::chrono::sys_time{std::chrono::seconds{birthday_in_second}};\n
Run Code Online (Sandbox Code Playgroud)\n

或者:

\n
std::chrono::sys_time{std::chrono::milliseconds{birthday_in_millisecond}};\n
Run Code Online (Sandbox Code Playgroud)\n
\n
    \n
  • 要添加/减去年份,您可以使用:
  • \n
\n
auto now = std::chrono::system_clock::now();\nauto today = std::chrono::year_month_day{std::chrono::floor<std::chrono::days>(now)};\nauto today_10_years_ago = today - std::chrono::years{10};\n
Run Code Online (Sandbox Code Playgroud)\n

您还可以使用using namespace std::chrono::literalswrite10y来代替years{10}.*这是不正确的,请参阅评论中的更多信息

\n

请注意today,现在today_10_years_ago是对象。year_month_day如果您time_point还想要包含 h/m/s 信息,您可以执行以下操作:

\n
auto today_as_time_point = std::chrono::sys_days{today_10_years_ago};\n\nauto time_only = today - now;\nauto today_with_time_info = today_as_time_point + time_only;\n
Run Code Online (Sandbox Code Playgroud)\n
\n
    \n
  • 是的,<chrono>图书馆在纪元之前的时间上工作。
  • \n
\n

根据要求,所有预定义的持续时间类型都chrono::hours保证在该范围内工作至少 \xc2\xb1292 年(实际上,其中许多类型仍将在更大的范围内工作)。并且类型大于小时,即。chrono::days,chrono::years保证 \xc2\xb140000 年。

\n

因此,如果您知道要做类似的事情now - years{1000},最好now先转换为更大的单位。

\n
\n
\n

我对选角还是有点不知所措……

\n
\n

该库的部分目标<chrono>是提供对时间/日期数据的高级访问,同时避免可能的错误。

\n

如果您想将更精确的持续时间转换为不太精确的持续时间,即。从毫秒到秒,您被迫使用显式强制转换或通过舍入,这将避免意外的截断错误。

\n

如需了解更多信息,您可以搜索 Howard Hinnant 关于图书馆的演讲。

\n
\n
\n

...并year从中提取类似的东西

\n
\n

根据您的需要,如果您的全部目标是序列化日期信息,您可能需要利用std::format{fmt} 库自动执行此操作:

\n
auto now = std::chrono::system_clock::now();\nstd::cout << std::format("{:%Y}", now);       // This will print only the year\n
Run Code Online (Sandbox Code Playgroud)\n

进一步利用格式化库进行演示。*注意{fmt}库被使用,因为 gcc 还没有实现完整的std::format库。

\n