время — c ++ получить миллисекунды с 01/01/0101 00:00:00

Мне нужна временная метка в специальном формате для вызова API:

Даты преобразуются в миллисекунды UTC, прошедшие с 12:00:00 до полуночи 1 января 0001 года.

Мое первое предположение было использовать:

auto now = std::chrono::system_clock::now();
std::cout << "millisceconds since epoch: "<< std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count()

Но, конечно же, вывод — это временной интервал эпохи UNIX
Thu Jan 1 00:00:00 1970

Так что для now = "Wed Dec 12 13:30:00 2018" это возвращается 1544617800000Миз.

Как получить миллисекунды с 12:00:00 до полуночи 1 января 0001 года?

Контекст OSISoft API

Документация API OSISoft для указания диапазона дат довольно странная

Запросы числового диапазона

Предыдущими примерами были Range Queries против строковых полей. Числовые значения> также можно искать с помощью Range Queries.

Единственными полями, которые проиндексированы как числовые поля, являются поля CreationDate и ChangeDate для соответствующих атрибутов PI Point. Для индексирования этих полей> добавьте их в список атрибутов PI Point. Эту конфигурацию можно просмотреть> или изменить на странице настроек.

Эти значения даты и времени индексируются как числовые значения посредством преобразования: даты преобразуются в миллисекунды UTC, прошедшие с 12:00:00 до полуночи 1 января 0001 года.

В следующем примере запрос представляет собой запрос на дату последнего изменения, равную или> превышающую 26 февраля, 22: 16: 50.000 (это универсальное время). Этот DateTime, после вышеупомянутого преобразования, будет представлен как числовое значение: 63655280210000. Поэтому отправленный запрос:

https://MyServer/piwebapi/search/query?q=changedate:[63655280210000 TO *]

Из этой документации я задал этот вопрос о том, как получить миллисекунды с 12:00:00 до полуночи 1 января 0001 года.

Я также связал Вопрос с PISquare

2

Решение

Не существует определенного способа расчета:

UTC миллисекунды истекли с 12:00:00 до полуночи 1 января 0001 года.

Судя по примерам, они используют тот же алгоритм, что и https://www.epochconverter.com/seconds-days-since-y0. Чтобы получить тот же результат, вы можете просто добавить 719162 дней в эпоху Unix:

auto now = std::chrono::system_clock::now();
std::cout << "millisceconds since epoch: "<< std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch() + std::chrono::hours(24 * 719162)).count()

Примечание C ++ 20 вводит std::chrono::days который вы могли бы использовать вместо 24 часов.
В зависимости от разрешения системных часов вам может потребоваться привести в миллисекунды перед добавлением смещения, чтобы избежать переполнения (719162 дней — это более 2 ^ 64 наносекунд).

4

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

Это легко использовать Библиотека дат / времени Говарда Хиннанта:

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

std::chrono::milliseconds
convert(std::chrono::system_clock::time_point tp)
{
using namespace date;
using namespace std::chrono;
return (floor<milliseconds>(tp) +
(sys_days{1970_y/January/1} - sys_days{1_y/January/1})).time_since_epoch();
}

int
main()
{
using namespace date;
using namespace std::chrono;
std::cout << convert(system_clock::now()) << '\n';
}

convert просто добавляет разницу между двумя эпохами к system_clock::time_pointусеченный до milliseconds точность, и извлекает duration вернуть как milliseconds,

Эта программа для меня просто вывод:

63680221359193ms

Диапазон на milliseconds достаточно большой, чтобы справиться с этим вычислением, но диапазон на вашем system_clock::time_point может не быть. Таким образом, важно усечь milliseconds сразу как сделано в коде выше, чтобы избежать переполнения.

0

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