создать std :: chrono :: high_resolution_clock :: time_point из двойного числа?

У меня есть таймеры, где время начала и окончания хранятся в базе данных 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

Решение

Вы не сможете использовать high_resolution_clock для этого, потому что эпоха для high_resolution_clock варьируется от платформы к платформе. Например, на моей платформе (OS X) эпоха high_resolution_clock всякий раз, когда я загружал свой компьютер. Эти часы с тех пор считаются наносекундами.

system_clock также имеет неопределенную эпоху. Тем не менее, все 3 реализации, которые мне известны, используют Unix Time в качестве своего определения. Поэтому, если вы готовы принять это наблюдение как факт, вы можете легко изменить time_points между юлианской эпохой и эпохой Unix Time, вычитая разницу между этими двумя эпохами.

То есть конвертировать юлианский time_point на время Unix time_point вычтите продолжительность времени с полудня в Гринвиче 24 ноября 4714 г. до н.э. до 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, чтобы преобразовать Б.С. годы до пролептических григорианских лет (1 год до н.э. — год 0, 2 год до н.э. — год -1 и т. д.). Я также вычитал полдня, чтобы учесть, что одна эпоха была в полдень, а другая — в полночь.

Если estimatedGrowFinishJulian это time_point представляющий количество дней с юлианской эпохи:

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

Тогда вы можете получить оценку в днях относительно эпохи Unix Time:

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

выводит число микросекунд (как двойное) между 14903312 днями после юлианской эпохи и сейчас (что довольно далеко в будущем).

4

Другие решения


По вопросам рекламы [email protected]