Мне нужна временная метка в специальном формате для вызова 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 года?
Документация 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
Не существует определенного способа расчета:
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 наносекунд).
Это легко использовать Библиотека дат / времени Говарда Хиннанта:
#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
сразу как сделано в коде выше, чтобы избежать переполнения.