从double创建std :: chrono :: high_resolution_clock :: time_point?

时间:2014-05-18 15:40:31

标签: c++ c++11 sqldatatypes chrono

我有定时器,其中开始和停止时间存储在SQLite数据库中。

我想将它们拉出来并创建std::chrono::high_resolution_clock::time_point,以便我可以将它们与now进行比较,看看还剩多少时间。

示例存储时间:14903312

typedef std::chrono::high_resolution_clock::time_point TP;

double _estimatedGrowFinish = o.getPlantTimeEstimatedGrowingStopped(); // `14903312`

TP _now = std::chrono::high_resolution_clock::now();

TP _end = ??

我只是不知道如何将我存储的双值转换为time_point,我可以在那里运行一些数学并决定剩下多少时间或者时间已经过去......

时间被放在数据库中,如:

std::chrono::high_resolution_clock::now() + std::chrono::seconds(20)

编辑:SQLite说这是关于日期和时代的

TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").

REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.

INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

1 个答案:

答案 0 :(得分:4)

您将无法使用high_resolution_clock,因为high_resolution_clock的纪元因平台而异。例如,在我的平台(OS X)上,每当我启动计算机时,high_resolution_clock的时代就是。从那时起,这个时钟只有几纳秒。

system_clock也有一个未指明的时代。但是,我所知道的所有3个实现都使用Unix Time作为它们的定义。因此,如果您愿意将此观察视为事实,您可以通过减去这两个时期之间的差异,轻松地在Julian时代和Unix时间时期之间转换time_point

即。将朱利安time_point转换为Unix时间time_point减去格林威治中午的时间,发生在公元前4714年11月24日。至1970-01-01 00:00:00 UTC。

为了做到这一点,这里有一些方便有效的日期算法:

http://howardhinnant.github.io/date_algorithms.html

例如,将这两个时期之间的天数设为double

double const JulianEpoch = days_from_civil(-4714+1, 11, 24) - 0.5;

注意+1转换B.C.到公元前几年(公元前1年,公元前2年,公元前1年,等等)。我还减去了半天的时间来解释中午的一个时期,而另一个时间是在午夜。

如果estimatedGrowFinishJuliantime_point,表示自朱利安时代以来的天数:

double estimatedGrowFinishJulian = getPlantTimeEstimatedGrowingStopped(); // `14903312`

然后,您可以获得与Unix时间纪元相关的估计天数:

double estimatedGrowFinishCivil = estimatedGrowFinishJulian + JulianEpoch;

请注意,这是time_point。它是time_point,其时代与std::system_clock的事实时期一致。您可以创建这样的time_point。为此,首先根据days创建double持续时间非常方便:

using days = std::chrono::duration
    <
        double,
        std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>
    >;

现在你可以说:

days estimatedGrowFinish(estimatedGrowFinishJulian + JulianEpoch);

回想一下,这仍然是duration,但它代表了system_clock时代以来的天数。因此它实际上是time_point。您可以使用:

创建此类time_point的类型
using DTP = std::chrono::time_point
    <
        std::chrono::system_clock,
        days
    >;

这是与time_point具有相同纪元的system_clock,并且每天记录一次,并将刻度计数存储为双精度。现在你可以:

DTP end(days(estimatedGrowFinishJulian + JulianEpoch));

time_point可与std::chrono::system_clock::now()进行比较,并从std::chrono::system_clock::now()中扣除。如果你减去它们,你将得到一个与duration具有相同精度的std::chrono::system_clock::period,但存储为双精度。在我的系统上,这是duration<double, micro>。所以:

std::cout << (end - now).count() << '\n';

在Julian时代之后的14903312天之间输出微秒数(作为一个双精度数)(现在已经很远了)。