Updated Examples and Recipes (markdown)

HowardHinnant
2015-08-02 11:51:57 -04:00
parent efb23b9217
commit c13be290d8

@@ -4,6 +4,7 @@ This page contains examples and recipes contributed by community members. Feel f
- [Obtaining a `time_point` from `y/m/d h:m:s` components](#time_point_to_components)
- [Obtaining `y/m/d h:m:s` components from a `time_point`](#components_to_time_point)
- [Normalizing `y/m/d` when it is `!ok()`](#normalize)
- [Converting from {year, microseconds} to CCSDS](#ccsds)
***
@@ -149,6 +150,48 @@ Outputs:
The specifications for these functions do not yet guarantee this "normalization behavior." But the implementation has been thoroughly tested for this behavior and the specification will be updated soon.
<a name="ccsds"></a>
### Converting from {year, microseconds} to CCSDS
(by [Howard Hinnant](https://github.com/HowardHinnant))
CCSDS (http://public.ccsds.org/default.aspx) has a data structure that looks like this:
struct CCSDS
{
std::uint16_t days;
std::uint32_t ms;
std::uint16_t us;
};
where `days` is the number of days since Jan 1, 1958, `ms` is the count of milliseconds of the current day, and `us` is the count of microseconds of the current millisecond.
A need arose to convert a {year, microsecond} data structure to the above CCSDS data structure, where the second component is the number of microseconds since the start of the year. Furthermore, the count of microseconds includes leap seconds.
Here is a function to perform that conversion:
CCSDS
to_CCSDS(date::year y, std::chrono::microseconds us)
{
using namespace date;
using namespace std::chrono;
auto utc = utc_clock::sys_to_utc(day_point(y/jan/1)) + us;
auto sys = utc_clock::utc_to_sys(utc);
auto dp = floor<days>(sys);
auto d = dp - day_point(1958_y/jan/1);
us = utc - utc_clock::sys_to_utc(dp);
auto ms = duration_cast<milliseconds>(us);
us -= ms;
return {static_cast<std::uint16_t>(d.count()),
static_cast<std::uint32_t>(ms.count()),
static_cast<std::uint16_t>(us.count())};
}
The variable `utc` holds the “year + us” as a time point with microseconds precision. This time point counts microseconds, including leap seconds, since 1970-01-01 00:00:00 UTC.
The next step is find when the day started that is associated with `utc`. To do this one must convert `utc` back to “Unix time”, and then truncate that time point to a precision of `days`, resulting in the variable `dp`. `dp` is a count of days since 1970-01-01. Since the required epoch is 1958-01-01, this is taken into account in creating `d`, the first value needed in the return type.
Now the number of microseconds since the start of the day needs to be computed. The start of the day, `dp`, is converted back into the leap-second aware system, and subtracted from the microsecond time point: `utc`. The variable `us` is reused to hold “microseconds since midnight”. Now it is a simple computation to split this into milliseconds since midnight, and microseconds since the last millisecond.
***
![CC BY Logo](http://mirrors.creativecommons.org/presskit/buttons/80x15/svg/by.svg) _This work is licensed under a [Creative Commons Attribution 4.0 International License](http://creativecommons.org/licenses/by/4.0/)._