У меня есть таймеры, где время начала и окончания хранятся в базе данных 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
варьируется от платформы к платформе. Например, на моей платформе (OS X) эпоха high_resolution_clock
всякий раз, когда я загружал свой компьютер. Эти часы с тех пор считаются наносекундами.
system_clock
также имеет неопределенную эпоху. Тем не менее, все 3 реализации, которые мне известны, используют Unix Time в качестве своего определения. Поэтому, если вы готовы принять это наблюдение как факт, вы можете легко изменить time_point
s между юлианской эпохой и эпохой 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 днями после юлианской эпохи и сейчас (что довольно далеко в будущем).