c ++ получить миллисекунды с 01/01/0101 00:00:00 - PullRequest
0 голосов
/ 12 декабря 2018

Мне нужна временная метка в специальном формате для вызова 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

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

Числовые диапазоны запросов

Предыдущими примерами были 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 ]

0 голосов
/ 12 декабря 2018

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

#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 голосов
/ 12 декабря 2018

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

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()

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

...