从双精度对象创建std::chrono::high_resolution_clock::time_point

creating an std::chrono::high_resolution_clock::time_point from a double?

本文关键字:resolution clock point time high chrono 双精度 对象 创建 std      更新时间:2023-10-16

我有计时器,其中开始和停止时间被存储在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.

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

system_clock也有一个未指定的纪元。然而,我所知道的所有3种实现都使用Unix Time作为它们的定义。因此,如果您愿意假设这个观察结果是事实,那么您可以通过减去这两个纪元之间的差值来轻松地在儒略历纪元和Unix时间纪元之间转换time_point s。

。要将儒略历时间time_point转换为Unix时间time_point,请减去从公元前4714年11月24日格林威治中午到UTC时间1970-01-01 00:00:00的时间长度。

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

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

例如,要以double的形式获取这两个epoch之间的天数:

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

注意+1将公元前年转换为预言的格里高利年(公元前1年是0年,公元前2年是-1年,等等)。我还减去了半天,以说明一个历元是在中午,另一个是在午夜。

如果estimatedGrowFinishJulian是一个time_point,表示自朱利安纪元以来的天数:

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

那么您就可以得到以天为单位的Unix时间纪元的估计:

double estimatedGrowFinishCivil = estimatedGrowFinishJulian + JulianEpoch;

注意这是一个time_point。它是一个time_point,其时代与std::system_clock的实际时代一致。您可以创建这样一个time_point。为此,首先可以方便地基于double创建days持续时间:

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
    >;

这是一个与system_clock具有相同epoch的time_point,它每天滴答一次,并将滴答计数存储为double类型。现在你可以:

DTP end(days(estimatedGrowFinishJulian + JulianEpoch));

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

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

输出从儒略历14903312天到现在(这是相当遥远的未来)之间的微秒数(以双精度表示)。