Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我该怎么做;“自大纪元以来的日子”;值与std::chrono配合得很好?_C++_Chrono - Fatal编程技术网

C++ 我该怎么做;“自大纪元以来的日子”;值与std::chrono配合得很好?

C++ 我该怎么做;“自大纪元以来的日子”;值与std::chrono配合得很好?,c++,chrono,C++,Chrono,我从一个神奇的小精灵那里得到了一个内存中非负整数值的数组,比如说I。其中每一个都表示某个纪元以来的天数(在ISO8601日历中,这比0早很多年) 现在,我想用C++类来包这些值——这些基本上是通过指针或重新解释的,它可以与 的代码进行交互,或者我应该说,它与通常使用 STD::StROO时间点和持续时间的代码一起使用。 我的最佳行动方案是什么?注意:我不想替换数组中的任何数据,也不想在其他地方为每个现有数据创建新值。如果它真的只是持续时间的问题,那么您可以简单地执行 std::chrono::d

我从一个神奇的小精灵那里得到了一个内存中非负整数值的数组,比如说
I
。其中每一个都表示某个纪元以来的天数(在ISO8601日历中,这比0早很多年)

现在,我想用C++类来包这些值——这些基本上是通过指针或重新解释的,它可以与 <代码>的代码进行交互,或者我应该说,它与通常使用 STD::StROO时间点和持续时间的代码一起使用。


我的最佳行动方案是什么?注意:我不想替换数组中的任何数据,也不想在其他地方为每个现有数据创建新值。

如果它真的只是持续时间的问题,那么您可以简单地执行

std::chrono::days(integer_value);
你会得到一个计时持续时间类型

其中每一个都表示从纪元开始的天数(在ISO8601日历中,这比0早很多年)

假设你指的是这个时代。这个时代与你的描述一致。链接上说这一纪元是公元前4714年11月24日,在公历的前公历中。我发现不用“BC”系统,而是使用负年份的系统更方便,因此在0年之间有一个平滑的数学过渡。在这个系统中,纪元是11月24日-4713日

使用,这是非常容易做到的。如果我选错了纪元,就在明显的地方换上正确的纪元

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

date::sys_days
to_sys_days(int i)
{
    using namespace date;
    return sys_days{days{i} -
        (sys_days{1970_y/January/1} - sys_days{-4713_y/November/24})};
}
这将产生:

2019-07-09 00:00:00.000000
to_sys_days
是一种非常便宜的操作。每次读取数据的单个元素时,您都可以这样做。它所做的只是从
i
中减去2440588。
至_sys_days
(铿锵++-O3)的优化机器代码为:

leal    -2440588(%rdi), %eax
即,所有类型更改业务都发生在编译时。它是免费的。运行时唯一发生的事情是历元偏移调整。这是必须执行的最小值,无论您的历元与
系统时钟
历元如何对齐

因此,如果有一个
int
数组作为数据,则不必复制整个数组。您只需根据需要转换其中的每个元素。例如:

void
display(std::chrono::system_clock::time_point tp)
{
    using date::operator<<;
    std::cout << tp << '\n';
}

int
main()
{
    display(to_sys_days(2'458'674));
}
int
main()
{
    int data[] = {2'458'674, 2'458'675, 2'458'676, 2'458'677, 2'458'678};
    for (auto i : data)
        display(to_sys_days(i));
}
输出:

2019-07-09 00:00:00.000000
2019-07-10 00:00:00.000000
2019-07-11 00:00:00.000000
2019-07-12 00:00:00.000000
2019-07-13 00:00:00.000000

如果您不想使用,您仍然可以完成工作,这只是多一点工作

首先创建一个
duration
类型,表示天数:

using days = std::chrono::duration
    <int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
我只需从历元差中减去12小时,然后让
auto
为我推断返回类型(现在是基于
系统时钟的
时间点
,精度为
小时

使用相同输入的完全相同的
显示
功能现在输出:

2019-07-09 12:00:00.000000

“自从时代以来”C++有严格的别名规则,所以你可能无法处理<代码> i>代码>,你可以把它添加到一个时间点。你需要把你的非负整数转换成一个日历,它可以覆盖那些整数所代表的所有日期/时间的范围。
std::chrono
system\u clock
stead\u clock
等)的时钟从某个固定时间点开始以秒为单位处理<代码>系统时钟
是唯一与挂钟时间相关的时钟。(其起源取决于硬件,但通常是1970年1月1日起的几秒钟)“在ISO 8601日历中比0早很多年”——这是什么?@NathanOliver:如果类的数据成员相同,我认为我可以安全地双关该类型。我不是吗?@DavidC.Rankin:std::chrono类以时钟为模板;我可以提供一个具有适当分辨率的时钟。这将不起作用,因为您使用了错误的纪元。2.我需要能够重新解释\u cast,而不是构造。@einpoklum由于严格的别名规则,您不能
在它们之间重新解释\u cast
。例如
struct A{intx;};结构B{int x;}
。您不能在
A
B
之间,也不能在
A
int
之间重新解释\u cast。(当然可以,但使用结果是无效的;唯一有效的方法是将
重新解释为原始类型并使用它,这在您的情况下是毫无意义的)。@einpoklum:指针或值,您不能通过指向A
B
的指针访问
A
,反之亦然。严格的别名规则就是这么说的。@Nicolas:1。在这种情况下,我担心我将不得不忽略这条规则,依靠编译器做我直觉认为正确的事情。2.但是如果
A::x
int
,那么
B::x
也是
A::x,这是否意味着,尽管有严格的别名规则,但实际上需要重新解释才能起作用?毕竟,
struct A
struct B
方法的代码实际上不能做出任何不同的假设。@Nicolas:或者,让我这样说,至少对我来说:在使用物理内存的机器上,这种内存在台式机、服务器和笔记本电脑上几乎无处不在,编译后的代码无法区分普通整数和作为
a::x
的一部分构造和使用的整数。
2019-07-09 12:00:00.000000