|
| 1 | +#pragma once |
| 2 | + |
| 3 | +/** |
| 4 | + * @file civil_time.hpp |
| 5 | + * @brief UTC date-time breakdown struct. |
| 6 | + * |
| 7 | + * Forward-declared in scales.hpp and fully defined here to avoid circular |
| 8 | + * dependencies. |
| 9 | + */ |
| 10 | + |
| 11 | +#include "ffi_core.hpp" |
| 12 | +#include <iomanip> |
| 13 | +#include <ostream> |
| 14 | + |
| 15 | +namespace tempoch { |
| 16 | + |
| 17 | +/** |
| 18 | + * @brief UTC date-time breakdown. |
| 19 | + * |
| 20 | + * A simple value type mirroring the C `tempoch_utc_t` struct. |
| 21 | + * |
| 22 | + * @code |
| 23 | + * tempoch::CivilTime noon(2000, 1, 1, 12, 0, 0); |
| 24 | + * auto jd = tempoch::JulianDate::from_utc(noon); |
| 25 | + * @endcode |
| 26 | + */ |
| 27 | +struct CivilTime { |
| 28 | + int32_t year; ///< Gregorian year (astronomical year numbering). |
| 29 | + uint8_t month; ///< Month [1, 12]. |
| 30 | + uint8_t day; ///< Day of month [1, 31]. |
| 31 | + uint8_t hour; ///< Hour [0, 23]. |
| 32 | + uint8_t minute; ///< Minute [0, 59]. |
| 33 | + uint8_t second; ///< Second [0, 60] (leap-second aware). |
| 34 | + uint32_t nanosecond; ///< Nanosecond [0, 999 999 999]. |
| 35 | + |
| 36 | + /// Default constructor: J2000 epoch noon-like civil representation. |
| 37 | + CivilTime() |
| 38 | + : year(2000), month(1), day(1), hour(12), minute(0), second(0), |
| 39 | + nanosecond(0) {} |
| 40 | + |
| 41 | + /** |
| 42 | + * @brief Construct from civil UTC components. |
| 43 | + */ |
| 44 | + CivilTime(int32_t y, uint8_t mo, uint8_t d, uint8_t h = 0, uint8_t mi = 0, |
| 45 | + uint8_t s = 0, uint32_t ns = 0) |
| 46 | + : year(y), month(mo), day(d), hour(h), minute(mi), second(s), |
| 47 | + nanosecond(ns) {} |
| 48 | + |
| 49 | + /// Convert to the C FFI struct. |
| 50 | + tempoch_utc_t to_c() const { |
| 51 | + return {year, month, day, hour, minute, second, nanosecond}; |
| 52 | + } |
| 53 | + |
| 54 | + /// Create from the C FFI struct. |
| 55 | + static CivilTime from_c(const tempoch_utc_t &c) { |
| 56 | + return CivilTime(c.year, c.month, c.day, c.hour, c.minute, c.second, |
| 57 | + c.nanosecond); |
| 58 | + } |
| 59 | +}; |
| 60 | + |
| 61 | +/// Stream CivilTime as YYYY-MM-DD HH:MM:SS[.nnnnnnnnn]. |
| 62 | +inline std::ostream &operator<<(std::ostream &os, const CivilTime &u) { |
| 63 | + const char prev = os.fill(); |
| 64 | + os << u.year << '-' << std::setfill('0') << std::setw(2) |
| 65 | + << static_cast<int>(u.month) << '-' << std::setw(2) |
| 66 | + << static_cast<int>(u.day) << ' ' << std::setw(2) |
| 67 | + << static_cast<int>(u.hour) << ':' << std::setw(2) |
| 68 | + << static_cast<int>(u.minute) << ':' << std::setw(2) |
| 69 | + << static_cast<int>(u.second); |
| 70 | + if (u.nanosecond != 0) |
| 71 | + os << '.' << std::setw(9) << u.nanosecond; |
| 72 | + os.fill(prev); |
| 73 | + return os; |
| 74 | +} |
| 75 | + |
| 76 | +} // namespace tempoch |
0 commit comments