I need a timestamp in a special format for an API call:
Dates are converted to UTC milliseconds elapsed since 12:00:00 midnight, January 1, 0001.
My first assumption was to use:
auto now = std::chrono::system_clock::now();
std::cout << "millisceconds since epoch: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()).count()
But of course the output is the time interval from the UNIX epoch
Thu Jan 1 00:00:00 1970
So for a now = "Wed Dec 12 13:30:00 2018"
it returns 1544617800000
ms.
How do I get the milliseconds elapsed since 12:00:00 midnight, January 1, 0001?
The OSISoft API Documentation for specifying a date range is quite strange
Numeric Range Queries
The previous examples were Range Queries against string fields. Numeric values > can also be searched for with Range Queries.
The only fields that are indexed as numeric fields are the CreationDate and ChangeDate fields for the respective PI Point attributes. To index these fields > add them to the list of PI Point Attributes. This configuration may be viewed > or modified on the Settings page.
These date time values are indexed as numeric values via a conversion: Dates are converted to UTC milliseconds elapsed since 12:00:00 midnight, January 1, 0001.
In the following example query is a request for last changed date equal to or > greater than February 26th, 22:16:50.000 (This is Universal Time). This DateTime, following the aforementioned conversion, would be represented as numeric value: 63655280210000. Therefore the query submitted is:
https://MyServer/piwebapi/search/query?q=changedate:[63655280210000 TO *]
From this documention I have asked this question on how to get the milliseconds elapsed since 12:00:00 midnight, January 1, 0001.
I also linked the Question to PISquare
There is no defined way to calculate:
UTC milliseconds elapsed since 12:00:00 midnight, January 1, 0001.
Judging by the examples they are using the same algorithm as https://www.epochconverter.com/seconds-days-since-y0. To get the same result you can just add 719162 days to the unix epoch:
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()
Note c++20 introduces std::chrono::days
which you could use instead of 24 hours.
Depending on the resolution of your system clock you may need to cast to milliseconds before adding the offset to avoid overflows (719162 days is more than 2^64 nanoseconds).