| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // This file is part of INSTINCT, the INS Toolkit for Integrated | ||
| 2 | // Navigation Concepts and Training by the Institute of Navigation of | ||
| 3 | // the University of Stuttgart, Germany. | ||
| 4 | // | ||
| 5 | // This Source Code Form is subject to the terms of the Mozilla Public | ||
| 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| 7 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
| 8 | |||
| 9 | /// @file InsTime.hpp | ||
| 10 | /// @brief The class is responsible for all time-related tasks | ||
| 11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
| 12 | /// @author T. Lambertus (tomke-jantje.lambertus@nav.uni-stuttgart.de) | ||
| 13 | /// @date 2020-12-02 | ||
| 14 | /// | ||
| 15 | /// @details This class contains all time-transformations functions. One instance is created for each InsTime object (defined in the structs). | ||
| 16 | /// Internally, only the MJD-time (Modified Julien Date) is stored (here MJD is a struct which has mjd_day and mjd_frac). | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <cstdint> | ||
| 21 | #include <string> | ||
| 22 | #include <array> | ||
| 23 | #include <limits> | ||
| 24 | #include <iostream> | ||
| 25 | #include <chrono> | ||
| 26 | |||
| 27 | #include <fmt/ostream.h> | ||
| 28 | #include "gcem.hpp" | ||
| 29 | |||
| 30 | #include <nlohmann/json.hpp> | ||
| 31 | using json = nlohmann::json; ///< json namespace | ||
| 32 | |||
| 33 | #include "TimeSystem.hpp" | ||
| 34 | #include "Navigation/Math/Math.hpp" | ||
| 35 | |||
| 36 | namespace NAV | ||
| 37 | { | ||
| 38 | /// @brief Utility Namespace for Time related tasks | ||
| 39 | namespace InsTimeUtil | ||
| 40 | { | ||
| 41 | constexpr int32_t END_OF_THE_CENTURY_MJD = 400000; ///< Modified Julian Date of the end of the century (15.01.2954) | ||
| 42 | constexpr int32_t WEEKS_PER_GPS_CYCLE = 1024; ///< Weeks per GPS cycle | ||
| 43 | constexpr int32_t DIFF_TO_6_1_1980_MJD = 44244; ///< 06.01.1980 in Modified Julian Date | ||
| 44 | constexpr int32_t DIFF_TO_1_1_1970_MJD = 40587; ///< 01.01.1970 00:00:00 UTC in Modified Julian Date (UNIX epoch) | ||
| 45 | constexpr int32_t DIFF_BDT_WEEK_TO_GPST_WEEK = 1356; ///< BeiDou starts zero at 1-Jan-2006 and GPS starts 6-Jan-1980 | ||
| 46 | |||
| 47 | constexpr int32_t DIFF_MJD_TO_JD_DAYS = 2400000; ///< Difference of the days between MJD and JD | ||
| 48 | constexpr long double DIFF_MJD_TO_JD_FRAC = 0.5L; ///< Difference of the fraction between MJD and JD | ||
| 49 | |||
| 50 | constexpr int32_t MONTHS_PER_YEAR = 12; ///< Months / Year | ||
| 51 | constexpr int32_t DAYS_PER_YEAR = 365; ///< Days / Year | ||
| 52 | constexpr int32_t DAYS_PER_WEEK = 7; ///< Days / Week | ||
| 53 | constexpr int32_t HOURS_PER_DAY = 24; ///< Hours / Day | ||
| 54 | constexpr int32_t HOURS_PER_WEEK = HOURS_PER_DAY * DAYS_PER_WEEK; ///< Hours / Week | ||
| 55 | constexpr int32_t MINUTES_PER_HOUR = 60; ///< Minutes / Hour | ||
| 56 | constexpr int32_t MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY; ///< Minutes / Day | ||
| 57 | constexpr int32_t MINUTES_PER_WEEK = MINUTES_PER_DAY * DAYS_PER_WEEK; ///< Minutes / Week | ||
| 58 | constexpr int32_t SECONDS_PER_MINUTE = 60; ///< Seconds / Minute | ||
| 59 | constexpr int32_t SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR; ///< Seconds / Hour | ||
| 60 | constexpr int32_t SECONDS_PER_DAY = SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY; ///< Seconds / Day | ||
| 61 | constexpr int32_t SECONDS_PER_WEEK = SECONDS_PER_DAY * DAYS_PER_WEEK; ///< Seconds / Week | ||
| 62 | |||
| 63 | /// Numerical precision/epsilon for 'long double' variables | ||
| 64 | /// - Linux/x64: 1e-19 | ||
| 65 | /// - Windows/x64 1e-16 | ||
| 66 | /// - Linux/armv8: 1e-34 (Epsilon reports too small precision. Real precision is only approx. 1e-17) | ||
| 67 | constexpr long double EPSILON = std::max(1e-17L, 10 * std::numeric_limits<long double>::epsilon()); | ||
| 68 | |||
| 69 | /// Maps GPS leap seconds to a time: array<mjd_day>, index + 1 is amount of leap seconds | ||
| 70 | constexpr std::array<int32_t, 20> GPS_LEAP_SEC_MJD = { | ||
| 71 | 0, // + 0 at 1 Jan 1980 and before | ||
| 72 | 44786, // + 1 at 1 Jul 1981 = diff UTC-TAI: 20 | ||
| 73 | 45151, // + 2 at 1 Jul 1982 = diff UTC-TAI: 21 | ||
| 74 | 45516, // + 3 at 1 Jul 1983 = diff UTC-TAI: 22 | ||
| 75 | 46247, // + 4 at 1 Jul 1985 = diff UTC-TAI: 23 | ||
| 76 | 47161, // + 5 at 1 Jan 1988 = diff UTC-TAI: 24 | ||
| 77 | 47892, // + 6 at 1 Jan 1990 = diff UTC-TAI: 25 | ||
| 78 | 48257, // + 7 at 1 Jan 1991 = diff UTC-TAI: 26 | ||
| 79 | 48804, // + 8 at 1 Jul 1992 = diff UTC-TAI: 27 | ||
| 80 | 49169, // + 9 at 1 Jul 1993 = diff UTC-TAI: 28 | ||
| 81 | 49534, // +10 at 1 Jul 1994 = diff UTC-TAI: 29 | ||
| 82 | 50083, // +11 at 1 Jan 1996 = diff UTC-TAI: 30 | ||
| 83 | 50630, // +12 at 1 Jul 1997 = diff UTC-TAI: 31 | ||
| 84 | 51179, // +13 at 1 Jan 1999 = diff UTC-TAI: 32 | ||
| 85 | 53736, // +14 at 1 Jan 2006 = diff UTC-TAI: 33 | ||
| 86 | 54832, // +15 at 1 Jan 2009 = diff UTC-TAI: 34 | ||
| 87 | 56109, // +16 at 1 Jul 2012 = diff UTC-TAI: 35 | ||
| 88 | 57204, // +17 at 1 Jul 2015 = diff UTC-TAI: 36 | ||
| 89 | 57754, // +18 at 1 Jan 2017 = diff UTC-TAI: 37 | ||
| 90 | 99999, // future | ||
| 91 | }; | ||
| 92 | |||
| 93 | /// @brief Returns true if the provided year is a leap year, false otherwise | ||
| 94 | /// @param[in] year The year to check | ||
| 95 | /// @return True if the year is a leap year, otherwise false | ||
| 96 | 816907 | constexpr bool isLeapYear(int32_t year) | |
| 97 | { | ||
| 98 |
6/6✓ Branch 0 taken 185932 times.
✓ Branch 1 taken 630975 times.
✓ Branch 2 taken 14403 times.
✓ Branch 3 taken 171529 times.
✓ Branch 4 taken 14345 times.
✓ Branch 5 taken 631033 times.
|
816907 | return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)); |
| 99 | } | ||
| 100 | |||
| 101 | /// @brief Returns the number of days in the specified month of the year | ||
| 102 | /// @param[in] month Month [1-12] | ||
| 103 | /// @param[in] year Year to determine the leap year | ||
| 104 | /// @return Number of days in the specified month | ||
| 105 | 243156 | constexpr int32_t daysInMonth(int32_t month, int32_t year) | |
| 106 | { | ||
| 107 | 243156 | --month; // Make month 0 based | |
| 108 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 243150 times.
|
243156 | if (month >= InsTimeUtil::MONTHS_PER_YEAR) |
| 109 | { | ||
| 110 | 6 | year += month / InsTimeUtil::MONTHS_PER_YEAR; | |
| 111 | 6 | month %= InsTimeUtil::MONTHS_PER_YEAR; | |
| 112 | } | ||
| 113 |
2/2✓ Branch 0 taken 3169 times.
✓ Branch 1 taken 243156 times.
|
246325 | while (month < 0) |
| 114 | { | ||
| 115 | 3169 | month += MONTHS_PER_YEAR; | |
| 116 | 3169 | year--; | |
| 117 | } | ||
| 118 | 243156 | ++month; // Make month 1 based | |
| 119 | |||
| 120 |
13/13✓ Branch 0 taken 91701 times.
✓ Branch 1 taken 15692 times.
✓ Branch 2 taken 11391 times.
✓ Branch 3 taken 8562 times.
✓ Branch 4 taken 7404 times.
✓ Branch 5 taken 40383 times.
✓ Branch 6 taken 5957 times.
✓ Branch 7 taken 17108 times.
✓ Branch 8 taken 9488 times.
✓ Branch 9 taken 9220 times.
✓ Branch 10 taken 11264 times.
✓ Branch 11 taken 14983 times.
✓ Branch 12 taken 3 times.
|
243156 | switch (month) |
| 121 | { | ||
| 122 | 91701 | case 1: | |
| 123 | 91701 | return 31; | |
| 124 | 15692 | case 2: | |
| 125 |
2/2✓ Branch 1 taken 12221 times.
✓ Branch 2 taken 3471 times.
|
15692 | if (isLeapYear(year)) |
| 126 | { | ||
| 127 | 12221 | return 29; | |
| 128 | } | ||
| 129 | 3471 | return 28; | |
| 130 | 11391 | case 3: | |
| 131 | 11391 | return 31; | |
| 132 | 8562 | case 4: | |
| 133 | 8562 | return 30; | |
| 134 | 7404 | case 5: | |
| 135 | 7404 | return 31; | |
| 136 | 40383 | case 6: | |
| 137 | 40383 | return 30; | |
| 138 | 5957 | case 7: | |
| 139 | 5957 | return 31; | |
| 140 | 17108 | case 8: | |
| 141 | 17108 | return 31; | |
| 142 | 9488 | case 9: | |
| 143 | 9488 | return 30; | |
| 144 | 9220 | case 10: | |
| 145 | 9220 | return 31; | |
| 146 | 11264 | case 11: | |
| 147 | 11264 | return 30; | |
| 148 | 14983 | case 12: | |
| 149 | 14983 | return 31; | |
| 150 | 3 | default: | |
| 151 | 3 | return 366; | |
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | /// @brief Formats a duration given in seconds into days, hours, minutes and seconds | ||
| 156 | /// @param[in] seconds Amount of seconds | ||
| 157 | /// @param[in] digits Digits to round the seconds to | ||
| 158 | /// @return Formatted string of the duration | ||
| 159 | 12 | constexpr std::string formatDuration(double seconds, size_t digits = 9) | |
| 160 | { | ||
| 161 | 12 | std::string str; | |
| 162 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
|
12 | if (seconds >= SECONDS_PER_DAY) |
| 163 | { | ||
| 164 | 4 | auto days = static_cast<int32_t>(seconds) / SECONDS_PER_DAY; | |
| 165 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
8 | str += fmt::format("{}{:d}d", str.empty() ? "" : " ", days); |
| 166 | 4 | seconds -= days * SECONDS_PER_DAY; | |
| 167 | } | ||
| 168 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
|
12 | if (seconds >= SECONDS_PER_HOUR) |
| 169 | { | ||
| 170 | 4 | auto hours = static_cast<int32_t>(seconds) / SECONDS_PER_HOUR; | |
| 171 |
3/4✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
8 | str += fmt::format("{}{:d}h", str.empty() ? "" : " ", hours); |
| 172 | 4 | seconds -= hours * SECONDS_PER_HOUR; | |
| 173 | } | ||
| 174 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
|
12 | if (seconds >= SECONDS_PER_MINUTE) |
| 175 | { | ||
| 176 | 4 | auto minutes = static_cast<int32_t>(seconds) / SECONDS_PER_MINUTE; | |
| 177 |
3/4✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
8 | str += fmt::format("{}{:d}m", str.empty() ? "" : " ", minutes); |
| 178 | 4 | seconds -= minutes * SECONDS_PER_MINUTE; | |
| 179 | } | ||
| 180 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
|
12 | if (seconds > 1e-9) |
| 181 | { | ||
| 182 | 6 | size_t d = 0; | |
| 183 |
1/2✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
|
30 | for (; d < digits + 1; d++) |
| 184 | { | ||
| 185 | 30 | if (2.0 * std::abs(std::round(seconds * std::pow(10.0, d)) - seconds * std::pow(10.0, d)) | |
| 186 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 24 times.
|
30 | < std::pow(10.0, -(static_cast<double>(digits) - static_cast<double>(d)))) |
| 187 | { | ||
| 188 | 6 | break; | |
| 189 | } | ||
| 190 | } | ||
| 191 |
3/4✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
|
12 | str += fmt::format("{}{:.{}f}s", str.empty() ? "" : " ", seconds, d); |
| 192 | } | ||
| 193 | 12 | return str; | |
| 194 | ✗ | } | |
| 195 | |||
| 196 | } // namespace InsTimeUtil | ||
| 197 | |||
| 198 | /// Modified Julien Date [UTC] | ||
| 199 | struct InsTime_MJD | ||
| 200 | { | ||
| 201 | int32_t mjd_day = 0; ///< Full days since 17. November 1858 [UTC] | ||
| 202 | long double mjd_frac = 0.0L; ///< Decimal fractions of a day of the Modified Julien Date [UTC] | ||
| 203 | |||
| 204 | /// @brief Default constructor | ||
| 205 | 799189 | constexpr InsTime_MJD() = default; | |
| 206 | |||
| 207 | /// @brief Constructor | ||
| 208 | /// @param[in] mjd_day Full days of the Modified Julien Date [UTC] | ||
| 209 | /// @param[in] mjd_frac Decimal fractions of a day of the Modified Julien Date [UTC] | ||
| 210 | 2475671 | constexpr InsTime_MJD(int32_t mjd_day, long double mjd_frac) | |
| 211 | 2475671 | : mjd_day(mjd_day), mjd_frac(mjd_frac) | |
| 212 | { | ||
| 213 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2475668 times.
|
2475671 | if (this->mjd_frac >= 1.0L) |
| 214 | { | ||
| 215 | 3 | this->mjd_day += static_cast<int32_t>(this->mjd_frac); | |
| 216 | 3 | this->mjd_frac -= static_cast<int32_t>(this->mjd_frac); | |
| 217 | } | ||
| 218 |
2/2✓ Branch 0 taken 172701 times.
✓ Branch 1 taken 2475671 times.
|
2648372 | while (this->mjd_frac < 0.0L) |
| 219 | { | ||
| 220 | 172701 | this->mjd_frac += 1.0L; | |
| 221 | 172701 | this->mjd_day--; | |
| 222 | } | ||
| 223 | 2475671 | } | |
| 224 | |||
| 225 | /// @brief Equal comparison operator (takes double precision into account) | ||
| 226 | /// @param[in] rhs Right-hand side to compare with | ||
| 227 | /// @return Comparison result | ||
| 228 | 7515235 | constexpr bool operator==(const InsTime_MJD& rhs) const | |
| 229 | { | ||
| 230 |
2/2✓ Branch 0 taken 7479686 times.
✓ Branch 1 taken 35549 times.
|
7515235 | if (mjd_day == rhs.mjd_day) |
| 231 | { | ||
| 232 | 7479686 | auto difference = gcem::abs(mjd_frac - rhs.mjd_frac); | |
| 233 | 7479570 | return difference <= InsTimeUtil::EPSILON; | |
| 234 | } | ||
| 235 | 71131 | if (auto diffDays = mjd_day - rhs.mjd_day; | |
| 236 |
2/2✓ Branch 1 taken 82 times.
✓ Branch 2 taken 35500 times.
|
35549 | gcem::abs(diffDays) == 1) |
| 237 | { | ||
| 238 | 82 | auto difference = 1 + diffDays * (mjd_frac - rhs.mjd_frac); | |
| 239 | 82 | return difference <= InsTimeUtil::EPSILON; | |
| 240 | } | ||
| 241 | 35500 | return false; | |
| 242 | } | ||
| 243 | /// @brief Inequal comparison operator (takes double precision into account) | ||
| 244 | /// @param[in] rhs Right-hand side to compare with | ||
| 245 | /// @return Comparison result | ||
| 246 | 258537 | constexpr bool operator!=(const InsTime_MJD& rhs) const | |
| 247 | { | ||
| 248 | 258537 | return !(*this == rhs); | |
| 249 | } | ||
| 250 | /// @brief Smaller or equal comparison operator (takes double precision into account) | ||
| 251 | /// @param[in] rhs Right-hand side to compare with | ||
| 252 | /// @return Comparison result | ||
| 253 | 20 | constexpr bool operator<=(const InsTime_MJD& rhs) const | |
| 254 | { | ||
| 255 |
3/4✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
20 | return *this < rhs || *this == rhs; |
| 256 | } | ||
| 257 | /// @brief Greater or equal comparison operator (takes double precision into account) | ||
| 258 | /// @param[in] rhs Right-hand side to compare with | ||
| 259 | /// @return Comparison result | ||
| 260 | 8 | constexpr bool operator>=(const InsTime_MJD& rhs) const | |
| 261 | { | ||
| 262 |
3/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
8 | return *this > rhs || *this == rhs; |
| 263 | } | ||
| 264 | /// @brief Smaller comparison operator (takes double precision into account) | ||
| 265 | /// @param[in] rhs Right-hand side to compare with | ||
| 266 | /// @return Comparison result | ||
| 267 | 1121518 | constexpr bool operator<(const InsTime_MJD& rhs) const | |
| 268 | { | ||
| 269 |
3/4✓ Branch 0 taken 1121601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 258264 times.
✓ Branch 3 taken 863337 times.
|
1121600 | return (mjd_day < rhs.mjd_day || (mjd_day == rhs.mjd_day && mjd_frac < rhs.mjd_frac)) |
| 270 |
3/4✓ Branch 0 taken 1121600 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 256273 times.
✓ Branch 4 taken 2125 times.
|
2243118 | && *this != rhs; |
| 271 | } | ||
| 272 | /// @brief Greater comparison operator (takes double precision into account) | ||
| 273 | /// @param[in] rhs Right-hand side to compare with | ||
| 274 | /// @return Comparison result | ||
| 275 | 12 | constexpr bool operator>(const InsTime_MJD& rhs) const | |
| 276 | { | ||
| 277 | 12 | return !(*this <= rhs); | |
| 278 | } | ||
| 279 | |||
| 280 | /// @brief Converts the object into a readable string | ||
| 281 | explicit operator std::string() const; | ||
| 282 | }; | ||
| 283 | |||
| 284 | /// Julien Date [UTC] | ||
| 285 | struct InsTime_JD | ||
| 286 | { | ||
| 287 | int32_t jd_day{}; ///< Full days since 1. January −4712 [UTC] | ||
| 288 | long double jd_frac{}; ///< Decimal fractions of a day of the Julien Date [UTC] | ||
| 289 | |||
| 290 | /// @brief Constructor | ||
| 291 | /// @param[in] jd_day Full days of the Julien Date [UTC] | ||
| 292 | /// @param[in] jd_frac Decimal fractions of a day of the Julien Date [UTC] | ||
| 293 | 242902 | constexpr InsTime_JD(int32_t jd_day, long double jd_frac) | |
| 294 | 242902 | : jd_day(jd_day), jd_frac(jd_frac) | |
| 295 | { | ||
| 296 |
2/2✓ Branch 0 taken 20140 times.
✓ Branch 1 taken 222762 times.
|
242902 | if (this->jd_frac >= 1.0L) |
| 297 | { | ||
| 298 | 20140 | this->jd_day += static_cast<int32_t>(this->jd_frac); | |
| 299 | 20140 | this->jd_frac -= static_cast<int32_t>(this->jd_frac); | |
| 300 | } | ||
| 301 |
2/2✓ Branch 0 taken 144408 times.
✓ Branch 1 taken 242902 times.
|
387310 | while (this->jd_frac < 0.0L) |
| 302 | { | ||
| 303 | 144408 | this->jd_frac += 1.0L; | |
| 304 | 144408 | this->jd_day--; | |
| 305 | } | ||
| 306 | 242902 | } | |
| 307 | |||
| 308 | /// @brief Equal comparison operator (takes double precision into account) | ||
| 309 | /// @param[in] rhs Right-hand side to compare with | ||
| 310 | /// @return Comparison result | ||
| 311 | 56 | constexpr bool operator==(const InsTime_JD& rhs) const | |
| 312 | { | ||
| 313 |
2/2✓ Branch 0 taken 36 times.
✓ Branch 1 taken 20 times.
|
56 | if (jd_day == rhs.jd_day) |
| 314 | { | ||
| 315 | 36 | auto difference = gcem::abs(jd_frac - rhs.jd_frac); | |
| 316 | 36 | return difference <= InsTimeUtil::EPSILON; | |
| 317 | } | ||
| 318 | 40 | if (auto diffDays = jd_day - rhs.jd_day; | |
| 319 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | gcem::abs(diffDays) == 1) |
| 320 | { | ||
| 321 | 20 | auto difference = 1 + diffDays * (jd_frac - rhs.jd_frac); | |
| 322 | 20 | return difference <= InsTimeUtil::EPSILON; | |
| 323 | } | ||
| 324 | ✗ | return false; | |
| 325 | } | ||
| 326 | /// @brief Inequal comparison operator (takes double precision into account) | ||
| 327 | /// @param[in] rhs Right-hand side to compare with | ||
| 328 | /// @return Comparison result | ||
| 329 | 28 | constexpr bool operator!=(const InsTime_JD& rhs) const | |
| 330 | { | ||
| 331 | 28 | return !(*this == rhs); | |
| 332 | } | ||
| 333 | /// @brief Smaller or equal comparison operator (takes double precision into account) | ||
| 334 | /// @param[in] rhs Right-hand side to compare with | ||
| 335 | /// @return Comparison result | ||
| 336 | 20 | constexpr bool operator<=(const InsTime_JD& rhs) const | |
| 337 | { | ||
| 338 |
3/4✓ Branch 1 taken 8 times.
✓ Branch 2 taken 12 times.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
20 | return *this < rhs || *this == rhs; |
| 339 | } | ||
| 340 | /// @brief Greater or equal comparison operator (takes double precision into account) | ||
| 341 | /// @param[in] rhs Right-hand side to compare with | ||
| 342 | /// @return Comparison result | ||
| 343 | 8 | constexpr bool operator>=(const InsTime_JD& rhs) const | |
| 344 | { | ||
| 345 |
3/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4 times.
|
8 | return *this > rhs || *this == rhs; |
| 346 | } | ||
| 347 | /// @brief Smaller comparison operator (takes double precision into account) | ||
| 348 | /// @param[in] rhs Right-hand side to compare with | ||
| 349 | /// @return Comparison result | ||
| 350 | 24 | constexpr bool operator<(const InsTime_JD& rhs) const | |
| 351 | { | ||
| 352 |
4/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 2 times.
|
16 | return (jd_day < rhs.jd_day || (jd_day == rhs.jd_day && jd_frac < rhs.jd_frac)) |
| 353 |
4/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 4 times.
|
40 | && *this != rhs; |
| 354 | } | ||
| 355 | /// @brief Greater comparison operator (takes double precision into account) | ||
| 356 | /// @param[in] rhs Right-hand side to compare with | ||
| 357 | /// @return Comparison result | ||
| 358 | 12 | constexpr bool operator>(const InsTime_JD& rhs) const | |
| 359 | { | ||
| 360 | 12 | return !(*this <= rhs); | |
| 361 | } | ||
| 362 | |||
| 363 | /// @brief Converts the object into a readable string | ||
| 364 | explicit operator std::string() const; | ||
| 365 | }; | ||
| 366 | |||
| 367 | /// GPS week and time of week in GPS standard time [GPST] | ||
| 368 | struct InsTime_GPSweekTow | ||
| 369 | { | ||
| 370 | int32_t gpsCycle{}; ///< Contains GPS cycle in GPS standard time [GPST] | ||
| 371 | int32_t gpsWeek{}; ///< Contains GPS week in GPS standard time [GPST] | ||
| 372 | long double tow{}; ///< Contains GPS time of week in seconds in GPS standard time [GPST] | ||
| 373 | |||
| 374 | /// @brief Constructor | ||
| 375 | /// @param[in] gpsCycle GPS cycle in GPS standard time [GPST] | ||
| 376 | /// @param[in] gpsWeek GPS week in GPS standard time [GPST] | ||
| 377 | /// @param[in] tow GPS time of week in seconds in GPS standard time [GPST] | ||
| 378 | 604359 | constexpr InsTime_GPSweekTow(int32_t gpsCycle, int32_t gpsWeek, long double tow) | |
| 379 | 604359 | : gpsCycle(gpsCycle), gpsWeek(gpsWeek), tow(tow) | |
| 380 | { | ||
| 381 |
2/2✓ Branch 0 taken 494620 times.
✓ Branch 1 taken 109739 times.
|
604359 | if (this->tow >= InsTimeUtil::SECONDS_PER_WEEK) |
| 382 | { | ||
| 383 | 494620 | this->gpsWeek += static_cast<int32_t>(this->tow / InsTimeUtil::SECONDS_PER_WEEK); | |
| 384 | 494620 | this->tow = gcem::fmod(this->tow, InsTimeUtil::SECONDS_PER_WEEK); | |
| 385 | } | ||
| 386 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 604353 times.
|
604353 | while (this->tow < 0.0L) |
| 387 | { | ||
| 388 | ✗ | this->tow += InsTimeUtil::SECONDS_PER_WEEK; | |
| 389 | ✗ | this->gpsWeek--; | |
| 390 | } | ||
| 391 | |||
| 392 |
2/2✓ Branch 0 taken 568324 times.
✓ Branch 1 taken 36029 times.
|
604353 | if (this->gpsWeek >= InsTimeUtil::WEEKS_PER_GPS_CYCLE) |
| 393 | { | ||
| 394 | 568324 | this->gpsCycle += this->gpsWeek / InsTimeUtil::WEEKS_PER_GPS_CYCLE; | |
| 395 | 568324 | this->gpsWeek %= InsTimeUtil::WEEKS_PER_GPS_CYCLE; | |
| 396 | } | ||
| 397 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 604353 times.
|
604353 | while (this->gpsWeek < 0) |
| 398 | { | ||
| 399 | ✗ | this->gpsWeek += InsTimeUtil::WEEKS_PER_GPS_CYCLE; | |
| 400 | ✗ | this->gpsCycle--; | |
| 401 | } | ||
| 402 | 604353 | }; | |
| 403 | |||
| 404 | /// @brief Equal comparison operator (takes double precision into account) | ||
| 405 | /// @param[in] rhs Right-hand side to compare with | ||
| 406 | /// @return Comparison result | ||
| 407 | 78 | constexpr bool operator==(const InsTime_GPSweekTow& rhs) const | |
| 408 | { | ||
| 409 |
4/4✓ Branch 0 taken 58 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 20 times.
|
78 | if (gpsCycle == rhs.gpsCycle && gpsWeek == rhs.gpsWeek) |
| 410 | { | ||
| 411 | 38 | return gcem::abs(tow - rhs.tow) <= InsTimeUtil::EPSILON; | |
| 412 | } | ||
| 413 | 80 | if (auto diffWeeks = gpsCycle * InsTimeUtil::WEEKS_PER_GPS_CYCLE + gpsWeek - (rhs.gpsCycle * InsTimeUtil::WEEKS_PER_GPS_CYCLE + rhs.gpsWeek); | |
| 414 |
2/2✓ Branch 1 taken 26 times.
✓ Branch 2 taken 14 times.
|
40 | gcem::abs(diffWeeks) == 1) |
| 415 | { | ||
| 416 | 26 | return gcem::abs(tow + diffWeeks * InsTimeUtil::SECONDS_PER_WEEK - rhs.tow) <= InsTimeUtil::EPSILON; | |
| 417 | } | ||
| 418 | 14 | return false; | |
| 419 | } | ||
| 420 | /// @brief Inequal comparison operator (takes double precision into account) | ||
| 421 | /// @param[in] rhs Right-hand side to compare with | ||
| 422 | /// @return Comparison result | ||
| 423 | 36 | constexpr bool operator!=(const InsTime_GPSweekTow& rhs) const | |
| 424 | { | ||
| 425 | 36 | return !(*this == rhs); | |
| 426 | } | ||
| 427 | /// @brief Smaller or equal comparison operator (takes double precision into account) | ||
| 428 | /// @param[in] rhs Right-hand side to compare with | ||
| 429 | /// @return Comparison result | ||
| 430 | 30 | constexpr bool operator<=(const InsTime_GPSweekTow& rhs) const | |
| 431 | { | ||
| 432 |
3/4✓ Branch 1 taken 12 times.
✓ Branch 2 taken 18 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
30 | return *this < rhs || *this == rhs; |
| 433 | } | ||
| 434 | /// @brief Greater or equal comparison operator (takes double precision into account) | ||
| 435 | /// @param[in] rhs Right-hand side to compare with | ||
| 436 | /// @return Comparison result | ||
| 437 | 12 | constexpr bool operator>=(const InsTime_GPSweekTow& rhs) const | |
| 438 | { | ||
| 439 |
3/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6 times.
|
12 | return *this > rhs || *this == rhs; |
| 440 | } | ||
| 441 | /// @brief Smaller comparison operator (takes double precision into account) | ||
| 442 | /// @param[in] rhs Right-hand side to compare with | ||
| 443 | /// @return Comparison result | ||
| 444 | 36 | constexpr bool operator<(const InsTime_GPSweekTow& rhs) const | |
| 445 | { | ||
| 446 | 36 | return (gpsCycle < rhs.gpsCycle | |
| 447 |
4/4✓ Branch 0 taken 26 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 8 times.
|
28 | || (gpsCycle == rhs.gpsCycle && gpsWeek < rhs.gpsWeek) |
| 448 |
6/6✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 8 times.
|
20 | || (gpsCycle == rhs.gpsCycle && gpsWeek == rhs.gpsWeek && tow < rhs.tow)) |
| 449 |
3/4✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
|
64 | && *this != rhs; |
| 450 | } | ||
| 451 | /// @brief Greater comparison operator (takes double precision into account) | ||
| 452 | /// @param[in] rhs Right-hand side to compare with | ||
| 453 | /// @return Comparison result | ||
| 454 | 18 | constexpr bool operator>(const InsTime_GPSweekTow& rhs) const | |
| 455 | { | ||
| 456 | 18 | return !(*this <= rhs); | |
| 457 | } | ||
| 458 | |||
| 459 | /// @brief Converts the object into a readable string | ||
| 460 | explicit operator std::string() const; | ||
| 461 | }; | ||
| 462 | |||
| 463 | /// Universal Time Coordinated [UTC] | ||
| 464 | struct InsTime_YMDHMS | ||
| 465 | { | ||
| 466 | int32_t year{}; ///< Contains year in Universal Time Coordinated [UTC] | ||
| 467 | int32_t month{}; ///< Contains month in Universal Time Coordinated [UTC] | ||
| 468 | int32_t day{}; ///< Contains day in Universal Time Coordinated [UTC] | ||
| 469 | int32_t hour{}; ///< Contains hour in Universal Time Coordinated [UTC] | ||
| 470 | int32_t min{}; ///< Contains minute in Universal Time Coordinated [UTC] | ||
| 471 | long double sec{}; ///< Contains second in Universal Time Coordinated [UTC] | ||
| 472 | |||
| 473 | /// @brief Constructor | ||
| 474 | /// @param[in] year Year in Universal Time Coordinated [UTC] | ||
| 475 | /// @param[in] month Month in Universal Time Coordinated (1 = January) [UTC] | ||
| 476 | /// @param[in] day Day in Universal Time Coordinated (1 = first day) [UTC] | ||
| 477 | /// @param[in] hour Hour in Universal Time Coordinated [UTC] | ||
| 478 | /// @param[in] min Minute in Universal Time Coordinated [UTC] | ||
| 479 | /// @param[in] sec Second in Universal Time Coordinated [UTC] | ||
| 480 | /// @param[in] digits Amount of digits for the seconds to round to | ||
| 481 | 243012 | constexpr InsTime_YMDHMS(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, long double sec, int digits = -1) | |
| 482 | 243012 | : year(year), month(month), day(day), hour(hour), min(min), sec(sec) | |
| 483 | { | ||
| 484 |
2/2✓ Branch 0 taken 2147 times.
✓ Branch 1 taken 240865 times.
|
243012 | if (digits >= 0) { this->sec = math::round(this->sec, static_cast<size_t>(digits)); } |
| 485 |
2/2✓ Branch 0 taken 54194 times.
✓ Branch 1 taken 188818 times.
|
243012 | if (this->sec >= InsTimeUtil::SECONDS_PER_MINUTE) |
| 486 | { | ||
| 487 | 54194 | this->min += static_cast<int32_t>(this->sec / InsTimeUtil::SECONDS_PER_MINUTE); | |
| 488 | 54194 | this->sec = gcem::fmod(this->sec, InsTimeUtil::SECONDS_PER_MINUTE); | |
| 489 | } | ||
| 490 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 243011 times.
|
243011 | while (this->sec < 0.0L) |
| 491 | { | ||
| 492 | ✗ | this->sec += InsTimeUtil::SECONDS_PER_MINUTE; | |
| 493 | ✗ | this->min--; | |
| 494 | } | ||
| 495 |
2/2✓ Branch 0 taken 2147 times.
✓ Branch 1 taken 240864 times.
|
243011 | if (digits >= 0) { this->sec = math::round(this->sec, static_cast<size_t>(digits)); } |
| 496 | |||
| 497 |
2/2✓ Branch 0 taken 52487 times.
✓ Branch 1 taken 190524 times.
|
243011 | if (this->min >= InsTimeUtil::MINUTES_PER_HOUR) |
| 498 | { | ||
| 499 | 52487 | this->hour += this->min / InsTimeUtil::MINUTES_PER_HOUR; | |
| 500 | 52487 | this->min %= InsTimeUtil::MINUTES_PER_HOUR; | |
| 501 | } | ||
| 502 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 243011 times.
|
243011 | while (this->min < 0) |
| 503 | { | ||
| 504 | ✗ | this->min += InsTimeUtil::MINUTES_PER_HOUR; | |
| 505 | ✗ | this->hour--; | |
| 506 | } | ||
| 507 | |||
| 508 |
2/2✓ Branch 0 taken 6409 times.
✓ Branch 1 taken 236602 times.
|
243011 | if (this->hour >= InsTimeUtil::HOURS_PER_DAY) |
| 509 | { | ||
| 510 | 6409 | this->day += this->hour / InsTimeUtil::HOURS_PER_DAY; | |
| 511 | 6409 | this->hour %= InsTimeUtil::HOURS_PER_DAY; | |
| 512 | } | ||
| 513 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 243011 times.
|
243011 | while (this->hour < 0) |
| 514 | { | ||
| 515 | ✗ | this->hour += InsTimeUtil::HOURS_PER_DAY; | |
| 516 | ✗ | this->day--; | |
| 517 | } | ||
| 518 | |||
| 519 |
2/2✓ Branch 1 taken 279095 times.
✓ Branch 2 taken 243016 times.
|
522105 | while (this->day >= InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year))) |
| 520 | { | ||
| 521 | 279095 | this->day -= InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year)); | |
| 522 | 279094 | this->year++; | |
| 523 | } | ||
| 524 | |||
| 525 |
2/2✓ Branch 1 taken 13 times.
✓ Branch 2 taken 243010 times.
|
243030 | while (this->day > InsTimeUtil::daysInMonth(this->month, this->year)) |
| 526 | { | ||
| 527 | 13 | this->day -= InsTimeUtil::daysInMonth(this->month, this->year); | |
| 528 | 14 | this->month++; | |
| 529 | } | ||
| 530 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 243010 times.
|
243012 | while (this->day < 1) |
| 531 | { | ||
| 532 | 2 | this->month--; | |
| 533 | 2 | this->day += InsTimeUtil::daysInMonth(this->month, this->year); | |
| 534 | } | ||
| 535 | |||
| 536 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 243010 times.
|
243016 | while (this->month > InsTimeUtil::MONTHS_PER_YEAR) |
| 537 | { | ||
| 538 | 6 | this->month -= InsTimeUtil::MONTHS_PER_YEAR; | |
| 539 | 6 | this->year++; | |
| 540 | } | ||
| 541 |
2/2✓ Branch 0 taken 3165 times.
✓ Branch 1 taken 243010 times.
|
246175 | while (this->month < 1) |
| 542 | { | ||
| 543 | 3165 | this->month += InsTimeUtil::MONTHS_PER_YEAR; | |
| 544 | 3165 | this->year--; | |
| 545 | } | ||
| 546 | 243010 | } | |
| 547 | |||
| 548 | /// @brief Equal comparison operator (takes double precision into account) | ||
| 549 | /// @param[in] rhs Right-hand side to compare with | ||
| 550 | /// @return Comparison result | ||
| 551 | 162 | constexpr bool operator==(const InsTime_YMDHMS& rhs) const | |
| 552 | { | ||
| 553 |
10/10✓ Branch 0 taken 142 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 114 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 93 times.
✓ Branch 7 taken 21 times.
✓ Branch 8 taken 86 times.
✓ Branch 9 taken 7 times.
|
162 | if (year == rhs.year && month == rhs.month && day == rhs.day && hour == rhs.hour && min == rhs.min) |
| 554 | { | ||
| 555 | 86 | return gcem::abs(sec - rhs.sec) <= InsTimeUtil::EPSILON; | |
| 556 | } | ||
| 557 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | InsTime_YMDHMS this_plus = InsTime_YMDHMS(this->year, this->month, this->day, this->hour, this->min, this->sec + 10); |
| 558 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | InsTime_YMDHMS rhs_plus = InsTime_YMDHMS(rhs.year, rhs.month, rhs.day, rhs.hour, rhs.min, rhs.sec + 10); |
| 559 |
10/10✓ Branch 0 taken 62 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 21 times.
✓ Branch 8 taken 6 times.
✓ Branch 9 taken 7 times.
|
76 | if (this_plus.year == rhs_plus.year && this_plus.month == rhs_plus.month && this_plus.day == rhs_plus.day && this_plus.hour == rhs_plus.hour && this_plus.min == rhs_plus.min) |
| 560 | { | ||
| 561 | 6 | return gcem::abs(this_plus.sec - rhs_plus.sec) <= InsTimeUtil::EPSILON; | |
| 562 | } | ||
| 563 | 70 | return false; | |
| 564 | } | ||
| 565 | /// @brief Inequal comparison operator (takes double precision into account) | ||
| 566 | /// @param[in] rhs Right-hand side to compare with | ||
| 567 | /// @return Comparison result | ||
| 568 | 73 | constexpr bool operator!=(const InsTime_YMDHMS& rhs) const | |
| 569 | { | ||
| 570 | 73 | return !(*this == rhs); | |
| 571 | } | ||
| 572 | /// @brief Smaller or equal comparison operator (takes double precision into account) | ||
| 573 | /// @param[in] rhs Right-hand side to compare with | ||
| 574 | /// @return Comparison result | ||
| 575 | 62 | constexpr bool operator<=(const InsTime_YMDHMS& rhs) const | |
| 576 | { | ||
| 577 |
3/4✓ Branch 1 taken 26 times.
✓ Branch 2 taken 36 times.
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
|
62 | return *this < rhs || *this == rhs; |
| 578 | } | ||
| 579 | /// @brief Greater or equal comparison operator (takes double precision into account) | ||
| 580 | /// @param[in] rhs Right-hand side to compare with | ||
| 581 | /// @return Comparison result | ||
| 582 | 25 | constexpr bool operator>=(const InsTime_YMDHMS& rhs) const | |
| 583 | { | ||
| 584 |
3/4✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 12 times.
|
25 | return *this > rhs || *this == rhs; |
| 585 | } | ||
| 586 | /// @brief Smaller comparison operator (takes double precision into account) | ||
| 587 | /// @param[in] rhs Right-hand side to compare with | ||
| 588 | /// @return Comparison result | ||
| 589 | 74 | constexpr bool operator<(const InsTime_YMDHMS& rhs) const | |
| 590 | { | ||
| 591 | 74 | return (year < rhs.year | |
| 592 |
4/4✓ Branch 0 taken 64 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 8 times.
|
66 | || (year == rhs.year && month < rhs.month) |
| 593 |
5/6✓ Branch 0 taken 56 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 8 times.
|
58 | || (year == rhs.year && month == rhs.month && day < rhs.day) |
| 594 |
6/8✓ Branch 0 taken 48 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✓ Branch 7 taken 12 times.
|
50 | || (year == rhs.year && month == rhs.month && day == rhs.day && hour < rhs.hour) |
| 595 |
7/10✓ Branch 0 taken 36 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 32 times.
✓ Branch 9 taken 4 times.
|
38 | || (year == rhs.year && month == rhs.month && day == rhs.day && hour == rhs.hour && min < rhs.min) |
| 596 |
8/12✓ Branch 0 taken 32 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 24 times.
|
34 | || (year == rhs.year && month == rhs.month && day == rhs.day && hour == rhs.hour && min == rhs.min && sec < rhs.sec)) |
| 597 |
3/4✓ Branch 0 taken 66 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
|
140 | && *this != rhs; |
| 598 | } | ||
| 599 | /// @brief Greater comparison operator (takes double precision into account) | ||
| 600 | /// @param[in] rhs Right-hand side to compare with | ||
| 601 | /// @return Comparison result | ||
| 602 | 37 | constexpr bool operator>(const InsTime_YMDHMS& rhs) const | |
| 603 | { | ||
| 604 | 37 | return !(*this <= rhs); | |
| 605 | } | ||
| 606 | |||
| 607 | /// @brief Converts the object into a readable string | ||
| 608 | explicit operator std::string() const; | ||
| 609 | }; | ||
| 610 | |||
| 611 | /// GPS year and day of year in GPS standard time [GPST] | ||
| 612 | struct InsTime_YDoySod | ||
| 613 | { | ||
| 614 | int32_t year{}; ///< Contains year in GPS standard time [GPST] | ||
| 615 | int32_t doy{}; ///< Contains day of year in GPS standard time [GPST] | ||
| 616 | long double sod{}; ///< Contains second of day in GPS standard time [GPST] | ||
| 617 | |||
| 618 | /// @brief Constructor | ||
| 619 | /// @param[in] year Year in GPS standard time [GPST] | ||
| 620 | /// @param[in] doy Day of year in GPS standard time [1-365(/366)] | ||
| 621 | /// @param[in] sod Second of day in GPS standard time [GPST] | ||
| 622 | 7 | constexpr InsTime_YDoySod(int32_t year, int32_t doy, long double sod) | |
| 623 | 7 | : year(year), doy(doy), sod(sod) | |
| 624 | { | ||
| 625 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (this->sod >= InsTimeUtil::SECONDS_PER_DAY) |
| 626 | { | ||
| 627 | ✗ | this->doy += static_cast<int32_t>(this->sod / InsTimeUtil::SECONDS_PER_DAY); | |
| 628 | ✗ | this->sod = gcem::fmod(this->sod, InsTimeUtil::SECONDS_PER_DAY); | |
| 629 | } | ||
| 630 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | while (this->sod < 0) |
| 631 | { | ||
| 632 | ✗ | this->sod += InsTimeUtil::SECONDS_PER_DAY; | |
| 633 | ✗ | this->doy--; | |
| 634 | } | ||
| 635 | |||
| 636 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
7 | while (this->doy > InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year))) |
| 637 | { | ||
| 638 | ✗ | this->doy -= InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year)); | |
| 639 | ✗ | this->year++; | |
| 640 | } | ||
| 641 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | while (this->doy < 1) |
| 642 | { | ||
| 643 | ✗ | this->doy += InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year - 1)); | |
| 644 | ✗ | this->year--; | |
| 645 | } | ||
| 646 | 7 | } | |
| 647 | |||
| 648 | /// @brief Equal comparison operator (takes double precision into account) | ||
| 649 | /// @param[in] rhs Right-hand side to compare with | ||
| 650 | /// @return Comparison result | ||
| 651 | 78 | constexpr bool operator==(const InsTime_YDoySod& rhs) const | |
| 652 | { | ||
| 653 |
4/4✓ Branch 0 taken 58 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 14 times.
|
78 | if (year == rhs.year && doy == rhs.doy) |
| 654 | { | ||
| 655 | 44 | return gcem::abs(sod - rhs.sod) <= InsTimeUtil::EPSILON; | |
| 656 | } | ||
| 657 | 68 | if (auto diffDays = year * InsTimeUtil::DAYS_PER_YEAR + doy - (rhs.year * InsTimeUtil::DAYS_PER_YEAR + rhs.doy); | |
| 658 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 14 times.
|
34 | gcem::abs(diffDays) == 1) |
| 659 | { | ||
| 660 | 20 | auto difference = gcem::abs(sod + diffDays * InsTimeUtil::SECONDS_PER_DAY - rhs.sod); | |
| 661 | 20 | return difference <= InsTimeUtil::EPSILON; | |
| 662 | } | ||
| 663 | 14 | return false; | |
| 664 | } | ||
| 665 | /// @brief Inequal comparison operator (takes double precision into account) | ||
| 666 | /// @param[in] rhs Right-hand side to compare with | ||
| 667 | /// @return Comparison result | ||
| 668 | 36 | constexpr bool operator!=(const InsTime_YDoySod& rhs) const | |
| 669 | { | ||
| 670 | 36 | return !(*this == rhs); | |
| 671 | } | ||
| 672 | /// @brief Smaller or equal comparison operator (takes double precision into account) | ||
| 673 | /// @param[in] rhs Right-hand side to compare with | ||
| 674 | /// @return Comparison result | ||
| 675 | 30 | constexpr bool operator<=(const InsTime_YDoySod& rhs) const | |
| 676 | { | ||
| 677 |
3/4✓ Branch 1 taken 12 times.
✓ Branch 2 taken 18 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
|
30 | return *this < rhs || *this == rhs; |
| 678 | } | ||
| 679 | /// @brief Greater or equal comparison operator (takes double precision into account) | ||
| 680 | /// @param[in] rhs Right-hand side to compare with | ||
| 681 | /// @return Comparison result | ||
| 682 | 12 | constexpr bool operator>=(const InsTime_YDoySod& rhs) const | |
| 683 | { | ||
| 684 |
3/4✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 6 times.
|
12 | return *this > rhs || *this == rhs; |
| 685 | } | ||
| 686 | /// @brief Smaller comparison operator (takes double precision into account) | ||
| 687 | /// @param[in] rhs Right-hand side to compare with | ||
| 688 | /// @return Comparison result | ||
| 689 | 36 | constexpr bool operator<(const InsTime_YDoySod& rhs) const | |
| 690 | { | ||
| 691 | 36 | return (year < rhs.year | |
| 692 |
4/4✓ Branch 0 taken 26 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 8 times.
|
28 | || (year == rhs.year && doy < rhs.doy) |
| 693 |
5/6✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 10 times.
|
20 | || (year == rhs.year && doy == rhs.doy && sod < rhs.sod)) |
| 694 |
3/4✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
|
64 | && *this != rhs; |
| 695 | } | ||
| 696 | /// @brief Greater comparison operator (takes double precision into account) | ||
| 697 | /// @param[in] rhs Right-hand side to compare with | ||
| 698 | /// @return Comparison result | ||
| 699 | 18 | constexpr bool operator>(const InsTime_YDoySod& rhs) const | |
| 700 | { | ||
| 701 | 18 | return !(*this <= rhs); | |
| 702 | } | ||
| 703 | |||
| 704 | /// @brief Converts the object into a readable string | ||
| 705 | explicit operator std::string() const; | ||
| 706 | }; | ||
| 707 | |||
| 708 | /// The class is responsible for all time-related tasks | ||
| 709 | class InsTime | ||
| 710 | { | ||
| 711 | public: | ||
| 712 | /* ------------------------------ Constructors ------------------------------ */ | ||
| 713 | |||
| 714 | /// @brief Default Constructor | ||
| 715 | 487923 | constexpr InsTime() = default; | |
| 716 | |||
| 717 | /// @brief Constructor | ||
| 718 | /// @param[in] mjd Time in Modified Julien Date | ||
| 719 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 720 | 32 | constexpr explicit InsTime(const InsTime_MJD& mjd, TimeSystem timesys = UTC) | |
| 721 | 32 | : _mjd(mjd) | |
| 722 | { | ||
| 723 |
2/4✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 32 times.
✗ Branch 6 not taken.
|
32 | *this -= std::chrono::duration<long double>(differenceToUTC(timesys)); |
| 724 | 32 | } | |
| 725 | |||
| 726 | /// @brief Constructor | ||
| 727 | /// @param[in] jd Time in Julien Date | ||
| 728 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 729 | 201548 | constexpr explicit InsTime(const InsTime_JD& jd, TimeSystem timesys = UTC) | |
| 730 | 201548 | : _mjd(jd.jd_day - InsTimeUtil::DIFF_MJD_TO_JD_DAYS, jd.jd_frac - InsTimeUtil::DIFF_MJD_TO_JD_FRAC) | |
| 731 | { | ||
| 732 |
2/4✓ Branch 1 taken 201535 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 201545 times.
✗ Branch 6 not taken.
|
201544 | *this -= std::chrono::duration<long double>(differenceToUTC(timesys)); |
| 733 | 201545 | } | |
| 734 | |||
| 735 | /// @brief Constructor | ||
| 736 | /// @param[in] gpsWeekTow Time as week and time of week | ||
| 737 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 738 | 109757 | constexpr explicit InsTime(const InsTime_GPSweekTow& gpsWeekTow, TimeSystem timesys = GPST) | |
| 739 | 109757 | { | |
| 740 | 109754 | auto mjd_day = static_cast<int32_t>((gpsWeekTow.gpsCycle * InsTimeUtil::WEEKS_PER_GPS_CYCLE + gpsWeekTow.gpsWeek) * InsTimeUtil::DAYS_PER_WEEK | |
| 741 | 109754 | + gcem::floor(gpsWeekTow.tow / InsTimeUtil::SECONDS_PER_DAY) | |
| 742 | 109718 | + InsTimeUtil::DIFF_TO_6_1_1980_MJD); | |
| 743 | 109718 | long double mjd_frac = gcem::fmod(gpsWeekTow.tow, InsTimeUtil::SECONDS_PER_DAY) / InsTimeUtil::SECONDS_PER_DAY; | |
| 744 | |||
| 745 | 109729 | _mjd = InsTime_MJD(mjd_day, mjd_frac); | |
| 746 | |||
| 747 |
2/4✓ Branch 1 taken 109692 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 109710 times.
✗ Branch 6 not taken.
|
109735 | *this -= std::chrono::duration<long double>(differenceToUTC(timesys)); |
| 748 | 109710 | } | |
| 749 | |||
| 750 | /// @brief Constructor | ||
| 751 | /// @param[in] yearMonthDayHMS Time in Universal Time Coordinated | ||
| 752 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 753 | 201529 | constexpr explicit InsTime(const InsTime_YMDHMS& yearMonthDayHMS, TimeSystem timesys = UTC) | |
| 754 | 201529 | { | |
| 755 | 201519 | auto a = static_cast<int32_t>((14 - yearMonthDayHMS.month) / static_cast<double>(InsTimeUtil::MONTHS_PER_YEAR)); | |
| 756 | 201519 | int32_t y = yearMonthDayHMS.year + 4800 - a; | |
| 757 | 201519 | int32_t m = yearMonthDayHMS.month + InsTimeUtil::MONTHS_PER_YEAR * a - 3; | |
| 758 | |||
| 759 | 201519 | auto jd_day = static_cast<int32_t>(yearMonthDayHMS.day | |
| 760 | 201519 | + gcem::floor((153.0 * static_cast<double>(m) + 2.0) / 5.0) | |
| 761 | 201514 | + y * InsTimeUtil::DAYS_PER_YEAR | |
| 762 | 201514 | + gcem::floor(static_cast<double>(y) / 4.0) | |
| 763 | 201518 | - gcem::floor(static_cast<double>(y) / 100.0) | |
| 764 | 201521 | + gcem::floor(static_cast<double>(y) / 400.0) | |
| 765 | 201525 | - 32045); | |
| 766 | 201525 | auto jd_frac = (yearMonthDayHMS.sec | |
| 767 | 201525 | + static_cast<long double>(yearMonthDayHMS.min) * InsTimeUtil::SECONDS_PER_MINUTE | |
| 768 | 201525 | + static_cast<long double>(yearMonthDayHMS.hour - 12.0) * InsTimeUtil::SECONDS_PER_HOUR) | |
| 769 | / InsTimeUtil::SECONDS_PER_DAY; | ||
| 770 | |||
| 771 |
2/4✓ Branch 3 taken 201523 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 201516 times.
✗ Branch 8 not taken.
|
201525 | _mjd = InsTime(InsTime_JD(jd_day, jd_frac)).toMJD(); |
| 772 | |||
| 773 |
2/4✓ Branch 1 taken 201523 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 201526 times.
✗ Branch 6 not taken.
|
201516 | *this -= std::chrono::duration<long double>(differenceToUTC(timesys)); |
| 774 | 201526 | } | |
| 775 | |||
| 776 | /// @brief Constructor | ||
| 777 | /// @param[in] yearDoySod Time as Year, day of year and seconds of day | ||
| 778 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 779 | 28 | constexpr explicit InsTime(const InsTime_YDoySod& yearDoySod, TimeSystem timesys = UTC) | |
| 780 | 28 | { | |
| 781 | 28 | auto year = yearDoySod.year; | |
| 782 | 28 | auto doy = yearDoySod.doy; | |
| 783 | 28 | auto sod = yearDoySod.sod; | |
| 784 | |||
| 785 | 28 | int32_t month = 1; | |
| 786 |
2/2✓ Branch 1 taken 34 times.
✓ Branch 2 taken 28 times.
|
62 | while (doy > InsTimeUtil::daysInMonth(month, year)) |
| 787 | { | ||
| 788 | 34 | doy -= InsTimeUtil::daysInMonth(month, year); | |
| 789 | 34 | month++; | |
| 790 | } | ||
| 791 | |||
| 792 |
3/6✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 28 times.
✗ Branch 10 not taken.
|
28 | _mjd = InsTime(InsTime_YMDHMS(year, month, doy, 0, 0, sod)).toMJD(); |
| 793 | |||
| 794 |
2/4✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
|
28 | *this -= std::chrono::duration<long double>(differenceToUTC(timesys)); |
| 795 | 28 | } | |
| 796 | |||
| 797 | /// @brief Constructor | ||
| 798 | /// @param[in] gpsCycle GPS cycle in GPS standard time | ||
| 799 | /// @param[in] gpsWeek GPS week in GPS standard time | ||
| 800 | /// @param[in] tow GPS time of week in GPS standard time | ||
| 801 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 802 | 81239 | constexpr InsTime(int32_t gpsCycle, int32_t gpsWeek, long double tow, TimeSystem timesys = GPST) | |
| 803 |
1/2✓ Branch 2 taken 81240 times.
✗ Branch 3 not taken.
|
81239 | : InsTime(InsTime_GPSweekTow(gpsCycle, gpsWeek, tow), timesys) {} |
| 804 | |||
| 805 | /// @brief Constructor | ||
| 806 | /// @param[in] year Year | ||
| 807 | /// @param[in] month Month (1 = January) | ||
| 808 | /// @param[in] day Day (1 = first day) | ||
| 809 | /// @param[in] hour Hour | ||
| 810 | /// @param[in] min Minute | ||
| 811 | /// @param[in] sec Second | ||
| 812 | /// @param[in] timesys Time System in which the previous values are given in | ||
| 813 | 201452 | constexpr InsTime(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, long double sec, TimeSystem timesys = UTC) | |
| 814 |
2/4✓ Branch 1 taken 201451 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 201456 times.
✗ Branch 5 not taken.
|
201452 | : InsTime(InsTime_YMDHMS(year, month, day, hour, min, sec), timesys) {} |
| 815 | |||
| 816 | /// @brief Destructor | ||
| 817 | ~InsTime() = default; | ||
| 818 | /// @brief Copy constructor | ||
| 819 | constexpr InsTime(const InsTime&) = default; | ||
| 820 | /// @brief Move constructor | ||
| 821 | constexpr InsTime(InsTime&&) = default; | ||
| 822 | /// @brief Copy assignment operator | ||
| 823 | constexpr InsTime& operator=(const InsTime&) = default; | ||
| 824 | /// @brief Move assignment operator | ||
| 825 | constexpr InsTime& operator=(InsTime&&) = default; | ||
| 826 | |||
| 827 | /* ------------------------ Transformation functions ------------------------ */ | ||
| 828 | |||
| 829 | /// @brief Converts this time object into a different format | ||
| 830 | /// @param timesys Time System in which the time should be given | ||
| 831 | /// @return InsTime_MJD structure of the this object | ||
| 832 | 482263 | [[nodiscard]] constexpr InsTime_MJD toMJD(TimeSystem timesys = UTC) const | |
| 833 | { | ||
| 834 | 482263 | long double mjdFrac = _mjd.mjd_frac + static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY); | |
| 835 | 482264 | return { _mjd.mjd_day, mjdFrac }; | |
| 836 | } | ||
| 837 | |||
| 838 | /// @brief Converts this time object into a different format | ||
| 839 | /// @param timesys Time System in which the time should be given | ||
| 840 | /// @return InsTime_JD structure of the this object | ||
| 841 | 41378 | [[nodiscard]] constexpr InsTime_JD toJD(TimeSystem timesys = UTC) const | |
| 842 | { | ||
| 843 | 41378 | auto jd_day = _mjd.mjd_day + InsTimeUtil::DIFF_MJD_TO_JD_DAYS; | |
| 844 | 41378 | auto jd_frac = _mjd.mjd_frac + InsTimeUtil::DIFF_MJD_TO_JD_FRAC; | |
| 845 | |||
| 846 | 41378 | jd_frac += static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY); | |
| 847 | |||
| 848 | 41378 | return { jd_day, jd_frac }; | |
| 849 | } | ||
| 850 | |||
| 851 | /// @brief Converts this time object into a different format | ||
| 852 | /// @param timesys Time System in which the time should be given | ||
| 853 | /// @return InsTime_GPSweekTow structure of the this object | ||
| 854 | 494619 | [[nodiscard]] constexpr InsTime_GPSweekTow toGPSweekTow(TimeSystem timesys = GPST) const | |
| 855 | { | ||
| 856 | 494619 | InsTime_MJD mjd_leap = _mjd; | |
| 857 | // Convert from UTC to intended time system | ||
| 858 |
1/2✓ Branch 1 taken 494616 times.
✗ Branch 2 not taken.
|
494619 | mjd_leap.mjd_frac += static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY); |
| 859 | |||
| 860 | // Put everything in the time of week, as it gets splitted in InsTime_GPSweekTow constructor | ||
| 861 | 494616 | auto tow = static_cast<long double>((mjd_leap.mjd_day - InsTimeUtil::DIFF_TO_6_1_1980_MJD)) * InsTimeUtil::SECONDS_PER_DAY | |
| 862 | 494616 | + mjd_leap.mjd_frac * InsTimeUtil::SECONDS_PER_DAY; | |
| 863 | |||
| 864 | 989229 | return { 0, 0, tow }; | |
| 865 | } | ||
| 866 | |||
| 867 | /// @brief Converts this time object into a different format | ||
| 868 | /// @param timesys Time System in which the time should be given | ||
| 869 | /// @param digits Amount of digits for the seconds to round to | ||
| 870 | /// @return InsTime_YMDHMS structure of the this object | ||
| 871 | 41374 | [[nodiscard]] constexpr InsTime_YMDHMS toYMDHMS(TimeSystem timesys = UTC, int digits = -1) const | |
| 872 | { | ||
| 873 | // transform MJD to JD | ||
| 874 |
1/2✓ Branch 2 taken 41378 times.
✗ Branch 3 not taken.
|
41374 | InsTime_JD jd = toJD(); |
| 875 | 41378 | jd.jd_frac = jd.jd_frac + 0.5L; | |
| 876 |
1/2✓ Branch 1 taken 41378 times.
✗ Branch 2 not taken.
|
41378 | jd.jd_frac += static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY); |
| 877 |
2/2✓ Branch 0 taken 21264 times.
✓ Branch 1 taken 20114 times.
|
41378 | if (jd.jd_frac >= 1.0L) |
| 878 | { | ||
| 879 | 21264 | jd.jd_day += static_cast<int32_t>(jd.jd_frac); | |
| 880 | 21264 | jd.jd_frac -= gcem::floor(jd.jd_frac); | |
| 881 | } | ||
| 882 | // transform JD to YMDHMS | ||
| 883 | 41378 | double a = 32044.0 + jd.jd_day; | |
| 884 | 41378 | double b = gcem::floor((4.0 * a + 3.0) / 146097.0); | |
| 885 | 41377 | double c = a - gcem::floor((b * 146097.0) / 4.0); | |
| 886 | |||
| 887 | 41376 | double d = gcem::floor((4.0 * c + 3.0) / 1461.0); | |
| 888 | 41377 | double e = c - gcem::floor((1461.0 * d) / 4.0); | |
| 889 | 41377 | double m = gcem::floor((5.0 * e + 2.0) / 153.0); | |
| 890 | |||
| 891 | 41378 | auto day = static_cast<uint16_t>(e - gcem::floor((153.0 * m + 2.0) / 5.0) + 1); | |
| 892 | 41378 | auto month = static_cast<uint16_t>(m + 3 - 12 * gcem::floor(m / 10.0)); | |
| 893 | 41378 | auto year = static_cast<uint16_t>(b * 100 + d - 4800.0 + gcem::floor(m / 10.0)); | |
| 894 | |||
| 895 | 41378 | long double sec = jd.jd_frac * InsTimeUtil::SECONDS_PER_DAY; | |
| 896 | |||
| 897 |
1/2✓ Branch 1 taken 41375 times.
✗ Branch 2 not taken.
|
82753 | return { year, month, day, 0, 0, sec, digits }; |
| 898 | } | ||
| 899 | |||
| 900 | /// @brief Converts this time object into a different format | ||
| 901 | /// @param timesys Time System in which the time should be given | ||
| 902 | /// @return InsTime_YDoySod structure of the this object | ||
| 903 | 4 | [[nodiscard]] constexpr InsTime_YDoySod toYDoySod(TimeSystem timesys = UTC) const | |
| 904 | { | ||
| 905 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | InsTime_YMDHMS yearMonthDayHMS = toYMDHMS(); |
| 906 | |||
| 907 | 4 | auto year = yearMonthDayHMS.year; | |
| 908 | 4 | long double sod = static_cast<long double>(yearMonthDayHMS.hour * InsTimeUtil::SECONDS_PER_HOUR | |
| 909 | 4 | + yearMonthDayHMS.min * InsTimeUtil::SECONDS_PER_MINUTE) | |
| 910 | 4 | + yearMonthDayHMS.sec | |
| 911 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | + static_cast<long double>(differenceToUTC(timesys)); |
| 912 | |||
| 913 | 4 | int32_t doy = 0; | |
| 914 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
|
18 | for (int32_t i = 1; i < yearMonthDayHMS.month; i++) |
| 915 | { | ||
| 916 | 14 | doy += InsTimeUtil::daysInMonth(i, year); | |
| 917 | } | ||
| 918 | 4 | doy += yearMonthDayHMS.day; | |
| 919 | |||
| 920 | 8 | return { year, doy, sod }; | |
| 921 | } | ||
| 922 | |||
| 923 | /// @brief Returns the current time rounded/cutted to a full day (changes time to 0:0:0h UTC of current day) | ||
| 924 | /// @return The rounded/cutted time object | ||
| 925 | [[nodiscard]] constexpr InsTime toFullDay() const | ||
| 926 | { | ||
| 927 | return InsTime(InsTime_MJD(_mjd.mjd_day, 0.0L)); | ||
| 928 | } | ||
| 929 | |||
| 930 | /// @brief Converts this time object into a UNIX timestamp in [s] | ||
| 931 | /// @attention Do not pass `long double` to the LOG_... functions, it can loop indefinitely | ||
| 932 | 4 | [[nodiscard]] constexpr long double toUnixTime() const | |
| 933 | { | ||
| 934 | 4 | return static_cast<long double>((_mjd.mjd_day - InsTimeUtil::DIFF_TO_1_1_1970_MJD) * InsTimeUtil::SECONDS_PER_DAY) | |
| 935 | 4 | + _mjd.mjd_frac * InsTimeUtil::SECONDS_PER_DAY; | |
| 936 | } | ||
| 937 | |||
| 938 | /* ----------------------------- Leap functions ----------------------------- */ | ||
| 939 | |||
| 940 | /// @brief Returns the current number of leap seconds (offset GPST to UTC) | ||
| 941 | /// @return Number of leap seconds | ||
| 942 | 957623 | [[nodiscard]] constexpr uint16_t leapGps2UTC() const | |
| 943 | { | ||
| 944 | 957623 | return leapGps2UTC(_mjd); | |
| 945 | } | ||
| 946 | |||
| 947 | /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime object | ||
| 948 | /// @param[in] insTime Time point | ||
| 949 | /// @return Number of leap seconds | ||
| 950 | 7 | static constexpr uint16_t leapGps2UTC(const InsTime& insTime) | |
| 951 | { | ||
| 952 | 7 | return leapGps2UTC(insTime._mjd); | |
| 953 | } | ||
| 954 | |||
| 955 | /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_GPSweekTow object | ||
| 956 | /// @param[in] gpsWeekTow Time point | ||
| 957 | /// @return Number of leap seconds | ||
| 958 | 1 | static constexpr uint16_t leapGps2UTC(const InsTime_GPSweekTow& gpsWeekTow) | |
| 959 | { | ||
| 960 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1 | return leapGps2UTC(InsTime(gpsWeekTow).toMJD()); |
| 961 | } | ||
| 962 | |||
| 963 | /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_YDoySod object | ||
| 964 | /// @param[in] yearDoySod Time point | ||
| 965 | /// @return Number of leap seconds | ||
| 966 | 1 | static constexpr uint16_t leapGps2UTC(const InsTime_YDoySod& yearDoySod) | |
| 967 | { | ||
| 968 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1 | return leapGps2UTC(InsTime(yearDoySod).toMJD()); |
| 969 | } | ||
| 970 | |||
| 971 | /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_YMDHMS object | ||
| 972 | /// @param[in] yearMonthDayHMS Time point | ||
| 973 | /// @return Number of leap seconds | ||
| 974 | 1 | static constexpr uint16_t leapGps2UTC(const InsTime_YMDHMS& yearMonthDayHMS) | |
| 975 | { | ||
| 976 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1 | return leapGps2UTC(InsTime(yearMonthDayHMS).toMJD()); |
| 977 | } | ||
| 978 | |||
| 979 | /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_JD object | ||
| 980 | /// @param[in] jd Time point | ||
| 981 | /// @return Number of leap seconds | ||
| 982 | 1 | static constexpr uint16_t leapGps2UTC(const InsTime_JD& jd) | |
| 983 | { | ||
| 984 |
3/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1 | return leapGps2UTC(InsTime(jd).toMJD()); |
| 985 | } | ||
| 986 | |||
| 987 | /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_MJD object | ||
| 988 | /// @param[in] mjd_in Time point | ||
| 989 | /// @return Number of leap seconds | ||
| 990 | 957628 | static constexpr uint16_t leapGps2UTC(const InsTime_MJD& mjd_in) | |
| 991 | { | ||
| 992 | 957628 | return static_cast<uint16_t>(std::ranges::upper_bound(InsTimeUtil::GPS_LEAP_SEC_MJD, mjd_in.mjd_day) - InsTimeUtil::GPS_LEAP_SEC_MJD.begin() - 1); | |
| 993 | } | ||
| 994 | |||
| 995 | /// @brief Checks if the current time is a leap year | ||
| 996 | /// @return True if the current time is a leap year, false otherwise | ||
| 997 | 1 | [[nodiscard]] constexpr bool isLeapYear() const | |
| 998 | { | ||
| 999 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | return InsTimeUtil::isLeapYear(toYMDHMS().year); |
| 1000 | } | ||
| 1001 | |||
| 1002 | /* --------------------- Comparison operator overloading -------------------- */ | ||
| 1003 | |||
| 1004 | /// @brief Equal comparison operator (takes double precision into account) | ||
| 1005 | /// @param[in] rhs Right-hand side to compare with | ||
| 1006 | /// @return Comparison result | ||
| 1007 | 7256897 | constexpr bool operator==(const InsTime& rhs) const { return _mjd == rhs._mjd; } | |
| 1008 | /// @brief Inequal comparison operator (takes double precision into account) | ||
| 1009 | /// @param[in] rhs Right-hand side to compare with | ||
| 1010 | /// @return Comparison result | ||
| 1011 | 86 | constexpr bool operator!=(const InsTime& rhs) const { return !(*this == rhs); } | |
| 1012 | /// @brief Smaller or equal comparison operator (takes double precision into account) | ||
| 1013 | /// @param[in] rhs Right-hand side to compare with | ||
| 1014 | /// @return Comparison result | ||
| 1015 |
4/4✓ Branch 1 taken 13063 times.
✓ Branch 2 taken 24627 times.
✓ Branch 4 taken 12869 times.
✓ Branch 5 taken 194 times.
|
37690 | constexpr bool operator<=(const InsTime& rhs) const { return *this < rhs || *this == rhs; } |
| 1016 | /// @brief Greater or equal comparison operator (takes double precision into account) | ||
| 1017 | /// @param[in] rhs Right-hand side to compare with | ||
| 1018 | /// @return Comparison result | ||
| 1019 |
4/4✓ Branch 1 taken 67 times.
✓ Branch 2 taken 141 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
|
208 | constexpr bool operator>=(const InsTime& rhs) const { return *this > rhs || *this == rhs; } |
| 1020 | /// @brief Smaller comparison operator (takes double precision into account) | ||
| 1021 | /// @param[in] rhs Right-hand side to compare with | ||
| 1022 | /// @return Comparison result | ||
| 1023 | 1121523 | constexpr bool operator<(const InsTime& rhs) const { return _mjd < rhs._mjd; } | |
| 1024 | /// @brief Greater comparison operator (takes double precision into account) | ||
| 1025 | /// @param[in] rhs Right-hand side to compare with | ||
| 1026 | /// @return Comparison result | ||
| 1027 | 30365 | constexpr bool operator>(const InsTime& rhs) const { return !(*this <= rhs); } | |
| 1028 | |||
| 1029 | /* --------------------- Arithmetic operator overloading -------------------- */ | ||
| 1030 | |||
| 1031 | /// @brief Substracts 2 points in time | ||
| 1032 | /// @param[in] lhs The left hand side time point | ||
| 1033 | /// @param[in] rhs The right hand side time point | ||
| 1034 | /// @return Time difference in [seconds] | ||
| 1035 | 3378380 | constexpr friend std::chrono::duration<long double> operator-(const InsTime& lhs, const InsTime& rhs) | |
| 1036 | { | ||
| 1037 | 3378380 | auto diffDays = lhs._mjd.mjd_day - rhs._mjd.mjd_day; | |
| 1038 | 3378380 | auto diffFrac = lhs._mjd.mjd_frac - rhs._mjd.mjd_frac; | |
| 1039 | 3378380 | long double diffSec = (diffFrac + static_cast<long double>(diffDays)) * InsTimeUtil::SECONDS_PER_DAY; | |
| 1040 | 3378380 | return std::chrono::duration<long double>(diffSec); | |
| 1041 | } | ||
| 1042 | |||
| 1043 | /// @brief Adds a duration to this time point | ||
| 1044 | /// @param[in] duration The duration to add | ||
| 1045 | /// @return Reference to this object | ||
| 1046 | 266204 | constexpr InsTime& operator+=(const std::chrono::duration<long double>& duration) | |
| 1047 | { | ||
| 1048 |
1/2✓ Branch 1 taken 266207 times.
✗ Branch 2 not taken.
|
266204 | auto duration_mjd_frac = std::chrono::duration<long double, std::ratio<InsTimeUtil::SECONDS_PER_DAY>>(duration).count(); |
| 1049 | 532424 | this->_mjd = InsTime_MJD(this->_mjd.mjd_day, | |
| 1050 | 266203 | this->_mjd.mjd_frac + duration_mjd_frac); | |
| 1051 | 266221 | return *this; | |
| 1052 | } | ||
| 1053 | |||
| 1054 | /// @brief Substracts a duration to this time point | ||
| 1055 | /// @param[in] duration The duration to substract | ||
| 1056 | /// @return Reference to this object | ||
| 1057 | 1415933 | constexpr InsTime& operator-=(const std::chrono::duration<long double>& duration) | |
| 1058 | { | ||
| 1059 |
1/2✓ Branch 1 taken 1415941 times.
✗ Branch 2 not taken.
|
1415933 | auto duration_mjd_frac = std::chrono::duration<long double, std::ratio<InsTimeUtil::SECONDS_PER_DAY>>(duration).count(); |
| 1060 | 2831938 | this->_mjd = InsTime_MJD(this->_mjd.mjd_day, | |
| 1061 | 1415908 | this->_mjd.mjd_frac - duration_mjd_frac); | |
| 1062 | 1416030 | return *this; | |
| 1063 | } | ||
| 1064 | |||
| 1065 | /// @brief Adds a duration to a time point | ||
| 1066 | /// @param[in] time The left hand side time point | ||
| 1067 | /// @param[in] duration The right hand side duration | ||
| 1068 | /// @return Time point with the added duration | ||
| 1069 | 265241 | constexpr friend InsTime operator+(const InsTime& time, const std::chrono::duration<long double>& duration) | |
| 1070 | { | ||
| 1071 |
1/2✓ Branch 1 taken 265253 times.
✗ Branch 2 not taken.
|
265241 | return InsTime(time) += duration; |
| 1072 | } | ||
| 1073 | |||
| 1074 | /// @brief Substracts a duration from a time point | ||
| 1075 | /// @param[in] time The left hand side time point | ||
| 1076 | /// @param[in] duration The right hand side duration | ||
| 1077 | /// @return Time point with the substracted duration | ||
| 1078 | 903143 | constexpr friend InsTime operator-(const InsTime& time, const std::chrono::duration<long double>& duration) | |
| 1079 | { | ||
| 1080 |
1/2✓ Branch 1 taken 903151 times.
✗ Branch 2 not taken.
|
903143 | return InsTime(time) -= duration; |
| 1081 | } | ||
| 1082 | |||
| 1083 | /* ---------------------------- Utility Functions --------------------------- */ | ||
| 1084 | |||
| 1085 | /// @brief Converts the object into a readable string | ||
| 1086 | explicit operator std::string() const; | ||
| 1087 | |||
| 1088 | /// @brief Checks if the Time object has a value | ||
| 1089 | 2756226 | [[nodiscard]] constexpr bool empty() const | |
| 1090 | { | ||
| 1091 |
3/4✓ Branch 0 taken 495054 times.
✓ Branch 1 taken 2261172 times.
✓ Branch 2 taken 495059 times.
✗ Branch 3 not taken.
|
2756226 | return _mjd.mjd_day == 0 && _mjd.mjd_frac == 0.0L; |
| 1092 | } | ||
| 1093 | |||
| 1094 | /// @brief Resets the InsTime object | ||
| 1095 | 225842 | void reset() | |
| 1096 | { | ||
| 1097 | 225842 | _mjd.mjd_day = 0; | |
| 1098 | 225842 | _mjd.mjd_frac = 0.0L; | |
| 1099 | 225842 | } | |
| 1100 | |||
| 1101 | /// @brief Adds the difference [seconds] between toe (OBRIT-0 last element) and toc (ORBIT-0 first element) to the current time | ||
| 1102 | /// (Changes time, so that it corresponds to the time of GLONASS ORBIT last element) | ||
| 1103 | /// @param[in] UTC_sec Seconds in UTC time | ||
| 1104 | void MakeTimeFromGloOrbit(double UTC_sec) | ||
| 1105 | { | ||
| 1106 | auto ymdhms = toYMDHMS(); | ||
| 1107 | // difference between toe (OBRIT-0 last element) and toc (ORBIT-0 first element) in seconds | ||
| 1108 | long double diff = gcem::fmod(static_cast<long double>(UTC_sec), InsTimeUtil::SECONDS_PER_DAY) | ||
| 1109 | - (ymdhms.hour * InsTimeUtil::SECONDS_PER_HOUR | ||
| 1110 | + ymdhms.min * InsTimeUtil::SECONDS_PER_MINUTE | ||
| 1111 | + ymdhms.sec); | ||
| 1112 | // std::cout << "orbit diff " << diff << "\n"; | ||
| 1113 | *this += std::chrono::duration<long double>(diff); | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | /// @brief Returns the time difference in [s] of a time system and UTC | ||
| 1117 | /// @param[in] timesys Time system to get the difference from UTC | ||
| 1118 | 1572574 | [[nodiscard]] constexpr int differenceToUTC(TimeSystem timesys) const | |
| 1119 | { | ||
| 1120 |
7/8✓ Branch 1 taken 768509 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 24616 times.
✓ Branch 4 taken 2404 times.
✓ Branch 5 taken 54 times.
✓ Branch 6 taken 21579 times.
✓ Branch 7 taken 755369 times.
✗ Branch 8 not taken.
|
1572574 | switch (TimeSystem_(timesys)) |
| 1121 | { | ||
| 1122 | 768509 | case GPST: // = GPS Time (UTC + leap_seconds) | |
| 1123 | 768509 | return this->leapGps2UTC(); | |
| 1124 | 17 | case GLNT: // = GLONASS Time (UTC+ 3h) | |
| 1125 | 17 | return 3 * InsTimeUtil::SECONDS_PER_HOUR; | |
| 1126 | 24616 | case GST: // = GALILEO Time (~ GPS) (UTC = GST - 18) is synchronized with TAI with a nominal offset below 50 ns | |
| 1127 | 24616 | return this->leapGps2UTC(); | |
| 1128 | 2404 | case QZSST: | |
| 1129 | 2404 | return this->leapGps2UTC(); // TODO citation for synchronization accuracy | |
| 1130 | 54 | case IRNSST: | |
| 1131 | 54 | return this->leapGps2UTC(); // TODO citation for synchronization accuracy | |
| 1132 | 21579 | case BDT: // = BeiDou Time (UTC) is synchronized with UTC within 100 ns< | |
| 1133 | 21579 | return this->leapGps2UTC() - 14; | |
| 1134 | 755369 | case UTC: | |
| 1135 | case TimeSys_None: | ||
| 1136 | 755369 | return 0; | |
| 1137 | } | ||
| 1138 | ✗ | return 0; | |
| 1139 | } | ||
| 1140 | |||
| 1141 | private: | ||
| 1142 | /// @brief Modified Julien Date of this InsTime object | ||
| 1143 | InsTime_MJD _mjd; | ||
| 1144 | }; | ||
| 1145 | |||
| 1146 | /// @brief Stream insertion operator overload | ||
| 1147 | /// @param[in, out] os Output stream object to stream the time into | ||
| 1148 | /// @param[in] mjd Object to print | ||
| 1149 | /// @return Returns the output stream object in order to chain stream insertions | ||
| 1150 | std::ostream& operator<<(std::ostream& os, const InsTime_MJD& mjd); | ||
| 1151 | /// @brief Stream insertion operator overload | ||
| 1152 | /// @param[in, out] os Output stream object to stream the time into | ||
| 1153 | /// @param[in] jd Object to print | ||
| 1154 | /// @return Returns the output stream object in order to chain stream insertions | ||
| 1155 | std::ostream& operator<<(std::ostream& os, const InsTime_JD& jd); | ||
| 1156 | /// @brief Stream insertion operator overload | ||
| 1157 | /// @param[in, out] os Output stream object to stream the time into | ||
| 1158 | /// @param[in] gpsWeekTow Object to print | ||
| 1159 | /// @return Returns the output stream object in order to chain stream insertions | ||
| 1160 | std::ostream& operator<<(std::ostream& os, const InsTime_GPSweekTow& gpsWeekTow); | ||
| 1161 | /// @brief Stream insertion operator overload | ||
| 1162 | /// @param[in, out] os Output stream object to stream the time into | ||
| 1163 | /// @param[in] ymdhms Object to print | ||
| 1164 | /// @return Returns the output stream object in order to chain stream insertions | ||
| 1165 | std::ostream& operator<<(std::ostream& os, const InsTime_YMDHMS& ymdhms); | ||
| 1166 | /// @brief Stream insertion operator overload | ||
| 1167 | /// @param[in, out] os Output stream object to stream the time into | ||
| 1168 | /// @param[in] yDoySod Object to print | ||
| 1169 | /// @return Returns the output stream object in order to chain stream insertions | ||
| 1170 | std::ostream& operator<<(std::ostream& os, const InsTime_YDoySod& yDoySod); | ||
| 1171 | /// @brief Stream insertion operator overload | ||
| 1172 | /// @param[in, out] os Output stream object to stream the time into | ||
| 1173 | /// @param[in] insTime Object to print | ||
| 1174 | /// @return Returns the output stream object in order to chain stream insertions | ||
| 1175 | std::ostream& operator<<(std::ostream& os, const InsTime& insTime); | ||
| 1176 | |||
| 1177 | /// @brief Converts the provided InsTime into a json object | ||
| 1178 | /// @param[out] j Return Json object | ||
| 1179 | /// @param[in] insTime Time to convert | ||
| 1180 | void to_json(json& j, const InsTime& insTime); | ||
| 1181 | /// @brief Converts the provided json object into an InsTime | ||
| 1182 | /// @param[in] j Json object with the time values | ||
| 1183 | /// @param[out] insTime Time to return | ||
| 1184 | void from_json(const json& j, InsTime& insTime); | ||
| 1185 | |||
| 1186 | } // namespace NAV | ||
| 1187 | |||
| 1188 | namespace std | ||
| 1189 | { | ||
| 1190 | /// @brief Hash function for InsTime (needed for unordered_map) | ||
| 1191 | template<> | ||
| 1192 | struct hash<NAV::InsTime> | ||
| 1193 | { | ||
| 1194 | /// @brief Hash function for InsTime | ||
| 1195 | /// @param[in] t Time | ||
| 1196 | std::size_t operator()(const NAV::InsTime& t) const | ||
| 1197 | { | ||
| 1198 | auto hash1 = std::hash<int32_t>{}(t.toMJD().mjd_day); | ||
| 1199 | auto hash2 = std::hash<long double>{}(t.toMJD().mjd_frac); | ||
| 1200 | |||
| 1201 | return hash1 | (hash2 << 32); | ||
| 1202 | } | ||
| 1203 | }; | ||
| 1204 | } // namespace std | ||
| 1205 | |||
| 1206 | #ifndef DOXYGEN_IGNORE | ||
| 1207 | |||
| 1208 | /// @brief Formatter | ||
| 1209 | template<> | ||
| 1210 | struct fmt::formatter<NAV::InsTime_MJD> : fmt::formatter<std::string> | ||
| 1211 | { | ||
| 1212 | /// @brief Defines how to format this structs | ||
| 1213 | /// @param[in] mjd Struct to format | ||
| 1214 | /// @param[in, out] ctx Format context | ||
| 1215 | /// @return Output iterator | ||
| 1216 | template<typename FormatContext> | ||
| 1217 | ✗ | auto format(const NAV::InsTime_MJD& mjd, FormatContext& ctx) const | |
| 1218 | { | ||
| 1219 | ✗ | return fmt::format_to(ctx.out(), "day={}, frac={}", mjd.mjd_day, static_cast<double>(mjd.mjd_frac)); | |
| 1220 | } | ||
| 1221 | }; | ||
| 1222 | /// @brief Formatter | ||
| 1223 | template<> | ||
| 1224 | struct fmt::formatter<NAV::InsTime_JD> : fmt::formatter<std::string> | ||
| 1225 | { | ||
| 1226 | /// @brief Defines how to format this structs | ||
| 1227 | /// @param[in] jd Struct to format | ||
| 1228 | /// @param[in, out] ctx Format context | ||
| 1229 | /// @return Output iterator | ||
| 1230 | template<typename FormatContext> | ||
| 1231 | ✗ | auto format(const NAV::InsTime_JD& jd, FormatContext& ctx) const | |
| 1232 | { | ||
| 1233 | ✗ | return fmt::format_to(ctx.out(), "day={}, frac={}", jd.jd_day, static_cast<double>(jd.jd_frac)); | |
| 1234 | } | ||
| 1235 | }; | ||
| 1236 | /// @brief Formatter | ||
| 1237 | template<> | ||
| 1238 | struct fmt::formatter<NAV::InsTime_GPSweekTow> : fmt::formatter<std::string> | ||
| 1239 | { | ||
| 1240 | /// @brief Defines how to format this structs | ||
| 1241 | /// @param[in] gpsWeekTow Struct to format | ||
| 1242 | /// @param[in, out] ctx Format context | ||
| 1243 | /// @return Output iterator | ||
| 1244 | template<typename FormatContext> | ||
| 1245 | 12954 | auto format(const NAV::InsTime_GPSweekTow& gpsWeekTow, FormatContext& ctx) const | |
| 1246 | { | ||
| 1247 | ✗ | return fmt::format_to(ctx.out(), "cycle={}, week={}, tow={}", | |
| 1248 |
1/2✓ Branch 1 taken 12954 times.
✗ Branch 2 not taken.
|
25908 | gpsWeekTow.gpsCycle, gpsWeekTow.gpsWeek, static_cast<double>(gpsWeekTow.tow)); |
| 1249 | } | ||
| 1250 | }; | ||
| 1251 | /// @brief Formatter | ||
| 1252 | template<> | ||
| 1253 | struct fmt::formatter<NAV::InsTime_YMDHMS> : fmt::formatter<std::string> | ||
| 1254 | { | ||
| 1255 | /// @brief Defines how to format this structs | ||
| 1256 | /// @param[in] ymdhms Struct to format | ||
| 1257 | /// @param[in, out] ctx Format context | ||
| 1258 | /// @return Output iterator | ||
| 1259 | template<typename FormatContext> | ||
| 1260 | 39203 | auto format(const NAV::InsTime_YMDHMS& ymdhms, FormatContext& ctx) const | |
| 1261 | { | ||
| 1262 | ✗ | return fmt::format_to(ctx.out(), "{}-{}-{} {}:{}:{:.6g}", | |
| 1263 | 39203 | ymdhms.year, ymdhms.month, ymdhms.day, | |
| 1264 |
1/2✓ Branch 1 taken 39202 times.
✗ Branch 2 not taken.
|
78405 | ymdhms.hour, ymdhms.min, static_cast<double>(ymdhms.sec)); |
| 1265 | } | ||
| 1266 | }; | ||
| 1267 | /// @brief Formatter | ||
| 1268 | template<> | ||
| 1269 | struct fmt::formatter<NAV::InsTime_YDoySod> : fmt::formatter<std::string> | ||
| 1270 | { | ||
| 1271 | /// @brief Defines how to format this structs | ||
| 1272 | /// @param[in] yDoySod Struct to format | ||
| 1273 | /// @param[in, out] ctx Format context | ||
| 1274 | /// @return Output iterator | ||
| 1275 | template<typename FormatContext> | ||
| 1276 | ✗ | auto format(const NAV::InsTime_YDoySod& yDoySod, FormatContext& ctx) const | |
| 1277 | { | ||
| 1278 | ✗ | return fmt::format_to(ctx.out(), "year={}, doy={}, sod={:.6g}", | |
| 1279 | ✗ | yDoySod.year, yDoySod.doy, static_cast<double>(yDoySod.sod)); | |
| 1280 | } | ||
| 1281 | }; | ||
| 1282 | /// @brief Formatter | ||
| 1283 | template<> | ||
| 1284 | struct fmt::formatter<NAV::InsTime> : fmt::formatter<std::string> | ||
| 1285 | { | ||
| 1286 | /// @brief Defines how to format this structs | ||
| 1287 | /// @param[in] insTime Struct to format | ||
| 1288 | /// @param[in, out] ctx Format context | ||
| 1289 | /// @return Output iterator | ||
| 1290 | template<typename FormatContext> | ||
| 1291 | 12902 | auto format(const NAV::InsTime& insTime, FormatContext& ctx) const | |
| 1292 | { | ||
| 1293 |
2/4✓ Branch 2 taken 12902 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 12902 times.
✗ Branch 7 not taken.
|
25804 | return fmt::format_to(ctx.out(), "{} ({})", insTime.toYMDHMS(), insTime.toGPSweekTow()); |
| 1294 | } | ||
| 1295 | }; | ||
| 1296 | |||
| 1297 | #endif | ||
| 1298 |