INSTINCT Code Coverage Report


Directory: src/
File: Navigation/Time/InsTime.hpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 384 411 93.4%
Functions: 77 80 96.2%
Branches: 277 359 77.2%

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 797006 constexpr bool isLeapYear(int32_t year)
97 {
98
6/6
✓ Branch 0 taken 166380 times.
✓ Branch 1 taken 630626 times.
✓ Branch 2 taken 14338 times.
✓ Branch 3 taken 152042 times.
✓ Branch 4 taken 14288 times.
✓ Branch 5 taken 630676 times.
797006 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 232637 constexpr int32_t daysInMonth(int32_t month, int32_t year)
106 {
107 232637 --month; // Make month 0 based
108
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 232631 times.
232637 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 3010 times.
✓ Branch 1 taken 232637 times.
235647 while (month < 0)
114 {
115 3010 month += MONTHS_PER_YEAR;
116 3010 year--;
117 }
118 232637 ++month; // Make month 1 based
119
120
13/13
✓ Branch 0 taken 96510 times.
✓ Branch 1 taken 6314 times.
✓ Branch 2 taken 11057 times.
✓ Branch 3 taken 8288 times.
✓ Branch 4 taken 7246 times.
✓ Branch 5 taken 38272 times.
✓ Branch 6 taken 5829 times.
✓ Branch 7 taken 15752 times.
✓ Branch 8 taken 9284 times.
✓ Branch 9 taken 9022 times.
✓ Branch 10 taken 10557 times.
✓ Branch 11 taken 14503 times.
✓ Branch 12 taken 3 times.
232637 switch (month)
121 {
122 96510 case 1:
123 96510 return 31;
124 6314 case 2:
125
2/2
✓ Branch 1 taken 2708 times.
✓ Branch 2 taken 3606 times.
6314 if (isLeapYear(year))
126 {
127 2708 return 29;
128 }
129 3606 return 28;
130 11057 case 3:
131 11057 return 31;
132 8288 case 4:
133 8288 return 30;
134 7246 case 5:
135 7246 return 31;
136 38272 case 6:
137 38272 return 30;
138 5829 case 7:
139 5829 return 31;
140 15752 case 8:
141 15752 return 31;
142 9284 case 9:
143 9284 return 30;
144 9022 case 10:
145 9022 return 31;
146 10557 case 11:
147 10557 return 30;
148 14503 case 12:
149 14503 return 31;
150 3 default:
151 3 return 366;
152 }
153 }
154 } // namespace InsTimeUtil
155
156 /// Modified Julien Date [UTC]
157 struct InsTime_MJD
158 {
159 int32_t mjd_day = 0; ///< Full days since 17. November 1858 [UTC]
160 long double mjd_frac = 0.0L; ///< Decimal fractions of a day of the Modified Julien Date [UTC]
161
162 /// @brief Default constructor
163 774746 constexpr InsTime_MJD() = default;
164
165 /// @brief Constructor
166 /// @param[in] mjd_day Full days of the Modified Julien Date [UTC]
167 /// @param[in] mjd_frac Decimal fractions of a day of the Modified Julien Date [UTC]
168 1392552 constexpr InsTime_MJD(int32_t mjd_day, long double mjd_frac)
169 1392552 : mjd_day(mjd_day), mjd_frac(mjd_frac)
170 {
171
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1392549 times.
1392552 if (this->mjd_frac >= 1.0L)
172 {
173 3 this->mjd_day += static_cast<int32_t>(this->mjd_frac);
174 3 this->mjd_frac -= static_cast<int32_t>(this->mjd_frac);
175 }
176
2/2
✓ Branch 0 taken 166319 times.
✓ Branch 1 taken 1392552 times.
1558871 while (this->mjd_frac < 0.0L)
177 {
178 166319 this->mjd_frac += 1.0L;
179 166319 this->mjd_day--;
180 }
181 1392552 }
182
183 /// @brief Equal comparison operator (takes double precision into account)
184 /// @param[in] rhs Right-hand side to compare with
185 /// @return Comparison result
186 7289013 constexpr bool operator==(const InsTime_MJD& rhs) const
187 {
188
2/2
✓ Branch 0 taken 7254379 times.
✓ Branch 1 taken 34634 times.
7289013 if (mjd_day == rhs.mjd_day)
189 {
190 7254379 auto difference = gcem::abs(mjd_frac - rhs.mjd_frac);
191 7254385 return difference <= InsTimeUtil::EPSILON;
192 }
193 69454 if (auto diffDays = mjd_day - rhs.mjd_day;
194
2/2
✓ Branch 1 taken 82 times.
✓ Branch 2 taken 34738 times.
34634 gcem::abs(diffDays) == 1)
195 {
196 82 auto difference = 1 + diffDays * (mjd_frac - rhs.mjd_frac);
197 82 return difference <= InsTimeUtil::EPSILON;
198 }
199 34738 return false;
200 }
201 /// @brief Inequal comparison operator (takes double precision into account)
202 /// @param[in] rhs Right-hand side to compare with
203 /// @return Comparison result
204 240380 constexpr bool operator!=(const InsTime_MJD& rhs) const
205 {
206 240380 return !(*this == rhs);
207 }
208 /// @brief Smaller or equal comparison operator (takes double precision into account)
209 /// @param[in] rhs Right-hand side to compare with
210 /// @return Comparison result
211 20 constexpr bool operator<=(const InsTime_MJD& rhs) const
212 {
213
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;
214 }
215 /// @brief Greater or equal comparison operator (takes double precision into account)
216 /// @param[in] rhs Right-hand side to compare with
217 /// @return Comparison result
218 8 constexpr bool operator>=(const InsTime_MJD& rhs) const
219 {
220
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;
221 }
222 /// @brief Smaller comparison operator (takes double precision into account)
223 /// @param[in] rhs Right-hand side to compare with
224 /// @return Comparison result
225 1067174 constexpr bool operator<(const InsTime_MJD& rhs) const
226 {
227
3/4
✓ Branch 0 taken 1067386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239933 times.
✓ Branch 3 taken 827453 times.
1067361 return (mjd_day < rhs.mjd_day || (mjd_day == rhs.mjd_day && mjd_frac < rhs.mjd_frac))
228
3/4
✓ Branch 0 taken 1067361 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 239127 times.
✓ Branch 4 taken 1084 times.
2134535 && *this != rhs;
229 }
230 /// @brief Greater comparison operator (takes double precision into account)
231 /// @param[in] rhs Right-hand side to compare with
232 /// @return Comparison result
233 12 constexpr bool operator>(const InsTime_MJD& rhs) const
234 {
235 12 return !(*this <= rhs);
236 }
237
238 /// @brief Converts the object into a readable string
239 explicit operator std::string() const;
240 };
241
242 /// Julien Date [UTC]
243 struct InsTime_JD
244 {
245 int32_t jd_day{}; ///< Full days since 1. January −4712 [UTC]
246 long double jd_frac{}; ///< Decimal fractions of a day of the Julien Date [UTC]
247
248 /// @brief Constructor
249 /// @param[in] jd_day Full days of the Julien Date [UTC]
250 /// @param[in] jd_frac Decimal fractions of a day of the Julien Date [UTC]
251 232388 constexpr InsTime_JD(int32_t jd_day, long double jd_frac)
252 232388 : jd_day(jd_day), jd_frac(jd_frac)
253 {
254
2/2
✓ Branch 0 taken 10671 times.
✓ Branch 1 taken 221717 times.
232388 if (this->jd_frac >= 1.0L)
255 {
256 10671 this->jd_day += static_cast<int32_t>(this->jd_frac);
257 10671 this->jd_frac -= static_cast<int32_t>(this->jd_frac);
258 }
259
2/2
✓ Branch 0 taken 138703 times.
✓ Branch 1 taken 232388 times.
371091 while (this->jd_frac < 0.0L)
260 {
261 138703 this->jd_frac += 1.0L;
262 138703 this->jd_day--;
263 }
264 232388 }
265
266 /// @brief Equal comparison operator (takes double precision into account)
267 /// @param[in] rhs Right-hand side to compare with
268 /// @return Comparison result
269 56 constexpr bool operator==(const InsTime_JD& rhs) const
270 {
271
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 20 times.
56 if (jd_day == rhs.jd_day)
272 {
273 36 auto difference = gcem::abs(jd_frac - rhs.jd_frac);
274 36 return difference <= InsTimeUtil::EPSILON;
275 }
276 40 if (auto diffDays = jd_day - rhs.jd_day;
277
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 gcem::abs(diffDays) == 1)
278 {
279 20 auto difference = 1 + diffDays * (jd_frac - rhs.jd_frac);
280 20 return difference <= InsTimeUtil::EPSILON;
281 }
282 return false;
283 }
284 /// @brief Inequal comparison operator (takes double precision into account)
285 /// @param[in] rhs Right-hand side to compare with
286 /// @return Comparison result
287 28 constexpr bool operator!=(const InsTime_JD& rhs) const
288 {
289 28 return !(*this == rhs);
290 }
291 /// @brief Smaller or equal comparison operator (takes double precision into account)
292 /// @param[in] rhs Right-hand side to compare with
293 /// @return Comparison result
294 20 constexpr bool operator<=(const InsTime_JD& rhs) const
295 {
296
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;
297 }
298 /// @brief Greater or equal comparison operator (takes double precision into account)
299 /// @param[in] rhs Right-hand side to compare with
300 /// @return Comparison result
301 8 constexpr bool operator>=(const InsTime_JD& rhs) const
302 {
303
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;
304 }
305 /// @brief Smaller comparison operator (takes double precision into account)
306 /// @param[in] rhs Right-hand side to compare with
307 /// @return Comparison result
308 24 constexpr bool operator<(const InsTime_JD& rhs) const
309 {
310
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))
311
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;
312 }
313 /// @brief Greater comparison operator (takes double precision into account)
314 /// @param[in] rhs Right-hand side to compare with
315 /// @return Comparison result
316 12 constexpr bool operator>(const InsTime_JD& rhs) const
317 {
318 12 return !(*this <= rhs);
319 }
320
321 /// @brief Converts the object into a readable string
322 explicit operator std::string() const;
323 };
324
325 /// GPS week and time of week in GPS standard time [GPST]
326 struct InsTime_GPSweekTow
327 {
328 int32_t gpsCycle{}; ///< Contains GPS cycle in GPS standard time [GPST]
329 int32_t gpsWeek{}; ///< Contains GPS week in GPS standard time [GPST]
330 long double tow{}; ///< Contains GPS time of week in seconds in GPS standard time [GPST]
331
332 /// @brief Constructor
333 /// @param[in] gpsCycle GPS cycle in GPS standard time [GPST]
334 /// @param[in] gpsWeek GPS week in GPS standard time [GPST]
335 /// @param[in] tow GPS time of week in seconds in GPS standard time [GPST]
336 240430 constexpr InsTime_GPSweekTow(int32_t gpsCycle, int32_t gpsWeek, long double tow)
337 240430 : gpsCycle(gpsCycle), gpsWeek(gpsWeek), tow(tow)
338 {
339
2/2
✓ Branch 0 taken 139342 times.
✓ Branch 1 taken 101088 times.
240430 if (this->tow >= InsTimeUtil::SECONDS_PER_WEEK)
340 {
341 139342 this->gpsWeek += static_cast<int32_t>(this->tow / InsTimeUtil::SECONDS_PER_WEEK);
342 139342 this->tow = gcem::fmod(this->tow, InsTimeUtil::SECONDS_PER_WEEK);
343 }
344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240430 times.
240430 while (this->tow < 0.0L)
345 {
346 this->tow += InsTimeUtil::SECONDS_PER_WEEK;
347 this->gpsWeek--;
348 }
349
350
2/2
✓ Branch 0 taken 210417 times.
✓ Branch 1 taken 30013 times.
240430 if (this->gpsWeek >= InsTimeUtil::WEEKS_PER_GPS_CYCLE)
351 {
352 210417 this->gpsCycle += this->gpsWeek / InsTimeUtil::WEEKS_PER_GPS_CYCLE;
353 210417 this->gpsWeek %= InsTimeUtil::WEEKS_PER_GPS_CYCLE;
354 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240430 times.
240430 while (this->gpsWeek < 0)
356 {
357 this->gpsWeek += InsTimeUtil::WEEKS_PER_GPS_CYCLE;
358 this->gpsCycle--;
359 }
360 240430 };
361
362 /// @brief Equal comparison operator (takes double precision into account)
363 /// @param[in] rhs Right-hand side to compare with
364 /// @return Comparison result
365 78 constexpr bool operator==(const InsTime_GPSweekTow& rhs) const
366 {
367
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)
368 {
369 38 return gcem::abs(tow - rhs.tow) <= InsTimeUtil::EPSILON;
370 }
371 80 if (auto diffWeeks = gpsCycle * InsTimeUtil::WEEKS_PER_GPS_CYCLE + gpsWeek - (rhs.gpsCycle * InsTimeUtil::WEEKS_PER_GPS_CYCLE + rhs.gpsWeek);
372
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 14 times.
40 gcem::abs(diffWeeks) == 1)
373 {
374 26 return gcem::abs(tow + diffWeeks * InsTimeUtil::SECONDS_PER_WEEK - rhs.tow) <= InsTimeUtil::EPSILON;
375 }
376 14 return false;
377 }
378 /// @brief Inequal comparison operator (takes double precision into account)
379 /// @param[in] rhs Right-hand side to compare with
380 /// @return Comparison result
381 36 constexpr bool operator!=(const InsTime_GPSweekTow& rhs) const
382 {
383 36 return !(*this == rhs);
384 }
385 /// @brief Smaller or equal comparison operator (takes double precision into account)
386 /// @param[in] rhs Right-hand side to compare with
387 /// @return Comparison result
388 30 constexpr bool operator<=(const InsTime_GPSweekTow& rhs) const
389 {
390
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;
391 }
392 /// @brief Greater or equal comparison operator (takes double precision into account)
393 /// @param[in] rhs Right-hand side to compare with
394 /// @return Comparison result
395 12 constexpr bool operator>=(const InsTime_GPSweekTow& rhs) const
396 {
397
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;
398 }
399 /// @brief Smaller comparison operator (takes double precision into account)
400 /// @param[in] rhs Right-hand side to compare with
401 /// @return Comparison result
402 36 constexpr bool operator<(const InsTime_GPSweekTow& rhs) const
403 {
404 36 return (gpsCycle < rhs.gpsCycle
405
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)
406
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))
407
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
64 && *this != rhs;
408 }
409 /// @brief Greater comparison operator (takes double precision into account)
410 /// @param[in] rhs Right-hand side to compare with
411 /// @return Comparison result
412 18 constexpr bool operator>(const InsTime_GPSweekTow& rhs) const
413 {
414 18 return !(*this <= rhs);
415 }
416
417 /// @brief Converts the object into a readable string
418 explicit operator std::string() const;
419 };
420
421 /// Universal Time Coordinated [UTC]
422 struct InsTime_YMDHMS
423 {
424 int32_t year{}; ///< Contains year in Universal Time Coordinated [UTC]
425 int32_t month{}; ///< Contains month in Universal Time Coordinated [UTC]
426 int32_t day{}; ///< Contains day in Universal Time Coordinated [UTC]
427 int32_t hour{}; ///< Contains hour in Universal Time Coordinated [UTC]
428 int32_t min{}; ///< Contains minute in Universal Time Coordinated [UTC]
429 long double sec{}; ///< Contains second in Universal Time Coordinated [UTC]
430
431 /// @brief Constructor
432 /// @param[in] year Year in Universal Time Coordinated [UTC]
433 /// @param[in] month Month in Universal Time Coordinated (1 = January) [UTC]
434 /// @param[in] day Day in Universal Time Coordinated (1 = first day) [UTC]
435 /// @param[in] hour Hour in Universal Time Coordinated [UTC]
436 /// @param[in] min Minute in Universal Time Coordinated [UTC]
437 /// @param[in] sec Second in Universal Time Coordinated [UTC]
438 /// @param[in] digits Amount of digits for the seconds to round to
439 232492 constexpr InsTime_YMDHMS(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, long double sec, int digits = -1)
440 232492 : year(year), month(month), day(day), hour(hour), min(min), sec(sec)
441 {
442
2/2
✓ Branch 0 taken 2147 times.
✓ Branch 1 taken 230345 times.
232492 if (digits >= 0) { this->sec = math::round(this->sec, static_cast<size_t>(digits)); }
443
2/2
✓ Branch 0 taken 52459 times.
✓ Branch 1 taken 180033 times.
232492 if (this->sec >= InsTimeUtil::SECONDS_PER_MINUTE)
444 {
445 52459 this->min += static_cast<int32_t>(this->sec / InsTimeUtil::SECONDS_PER_MINUTE);
446 52459 this->sec = gcem::fmod(this->sec, InsTimeUtil::SECONDS_PER_MINUTE);
447 }
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 232492 times.
232492 while (this->sec < 0.0L)
449 {
450 this->sec += InsTimeUtil::SECONDS_PER_MINUTE;
451 this->min--;
452 }
453
2/2
✓ Branch 0 taken 2147 times.
✓ Branch 1 taken 230345 times.
232492 if (digits >= 0) { this->sec = math::round(this->sec, static_cast<size_t>(digits)); }
454
455
2/2
✓ Branch 0 taken 50755 times.
✓ Branch 1 taken 181737 times.
232492 if (this->min >= InsTimeUtil::MINUTES_PER_HOUR)
456 {
457 50755 this->hour += this->min / InsTimeUtil::MINUTES_PER_HOUR;
458 50755 this->min %= InsTimeUtil::MINUTES_PER_HOUR;
459 }
460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 232492 times.
232492 while (this->min < 0)
461 {
462 this->min += InsTimeUtil::MINUTES_PER_HOUR;
463 this->hour--;
464 }
465
466
2/2
✓ Branch 0 taken 6409 times.
✓ Branch 1 taken 226083 times.
232492 if (this->hour >= InsTimeUtil::HOURS_PER_DAY)
467 {
468 6409 this->day += this->hour / InsTimeUtil::HOURS_PER_DAY;
469 6409 this->hour %= InsTimeUtil::HOURS_PER_DAY;
470 }
471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 232492 times.
232492 while (this->hour < 0)
472 {
473 this->hour += InsTimeUtil::HOURS_PER_DAY;
474 this->day--;
475 }
476
477
2/2
✓ Branch 1 taken 279090 times.
✓ Branch 2 taken 232492 times.
511586 while (this->day >= InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year)))
478 {
479 279090 this->day -= InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year));
480 279094 this->year++;
481 }
482
483
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 232496 times.
232506 while (this->day > InsTimeUtil::daysInMonth(this->month, this->year))
484 {
485 14 this->day -= InsTimeUtil::daysInMonth(this->month, this->year);
486 14 this->month++;
487 }
488
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 232496 times.
232498 while (this->day < 1)
489 {
490 2 this->month--;
491 2 this->day += InsTimeUtil::daysInMonth(this->month, this->year);
492 }
493
494
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 232496 times.
232502 while (this->month > InsTimeUtil::MONTHS_PER_YEAR)
495 {
496 6 this->month -= InsTimeUtil::MONTHS_PER_YEAR;
497 6 this->year++;
498 }
499
2/2
✓ Branch 0 taken 3006 times.
✓ Branch 1 taken 232496 times.
235502 while (this->month < 1)
500 {
501 3006 this->month += InsTimeUtil::MONTHS_PER_YEAR;
502 3006 this->year--;
503 }
504 232496 }
505
506 /// @brief Equal comparison operator (takes double precision into account)
507 /// @param[in] rhs Right-hand side to compare with
508 /// @return Comparison result
509 162 constexpr bool operator==(const InsTime_YMDHMS& rhs) const
510 {
511
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)
512 {
513 86 return gcem::abs(sec - rhs.sec) <= InsTimeUtil::EPSILON;
514 }
515
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);
516
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);
517
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)
518 {
519 6 return gcem::abs(this_plus.sec - rhs_plus.sec) <= InsTimeUtil::EPSILON;
520 }
521 70 return false;
522 }
523 /// @brief Inequal comparison operator (takes double precision into account)
524 /// @param[in] rhs Right-hand side to compare with
525 /// @return Comparison result
526 73 constexpr bool operator!=(const InsTime_YMDHMS& rhs) const
527 {
528 73 return !(*this == rhs);
529 }
530 /// @brief Smaller or equal comparison operator (takes double precision into account)
531 /// @param[in] rhs Right-hand side to compare with
532 /// @return Comparison result
533 62 constexpr bool operator<=(const InsTime_YMDHMS& rhs) const
534 {
535
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;
536 }
537 /// @brief Greater or equal comparison operator (takes double precision into account)
538 /// @param[in] rhs Right-hand side to compare with
539 /// @return Comparison result
540 25 constexpr bool operator>=(const InsTime_YMDHMS& rhs) const
541 {
542
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;
543 }
544 /// @brief Smaller comparison operator (takes double precision into account)
545 /// @param[in] rhs Right-hand side to compare with
546 /// @return Comparison result
547 74 constexpr bool operator<(const InsTime_YMDHMS& rhs) const
548 {
549 74 return (year < rhs.year
550
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)
551
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)
552
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)
553
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)
554
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))
555
3/4
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
140 && *this != rhs;
556 }
557 /// @brief Greater comparison operator (takes double precision into account)
558 /// @param[in] rhs Right-hand side to compare with
559 /// @return Comparison result
560 37 constexpr bool operator>(const InsTime_YMDHMS& rhs) const
561 {
562 37 return !(*this <= rhs);
563 }
564
565 /// @brief Converts the object into a readable string
566 explicit operator std::string() const;
567 };
568
569 /// GPS year and day of year in GPS standard time [GPST]
570 struct InsTime_YDoySod
571 {
572 int32_t year{}; ///< Contains year in GPS standard time [GPST]
573 int32_t doy{}; ///< Contains day of year in GPS standard time [GPST]
574 long double sod{}; ///< Contains second of day in GPS standard time [GPST]
575
576 /// @brief Constructor
577 /// @param[in] year Year in GPS standard time [GPST]
578 /// @param[in] doy Day of year in GPS standard time [1-365(/366)]
579 /// @param[in] sod Second of day in GPS standard time [GPST]
580 7 constexpr InsTime_YDoySod(int32_t year, int32_t doy, long double sod)
581 7 : year(year), doy(doy), sod(sod)
582 {
583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (this->sod >= InsTimeUtil::SECONDS_PER_DAY)
584 {
585 this->doy += static_cast<int32_t>(this->sod / InsTimeUtil::SECONDS_PER_DAY);
586 this->sod = gcem::fmod(this->sod, InsTimeUtil::SECONDS_PER_DAY);
587 }
588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 while (this->sod < 0)
589 {
590 this->sod += InsTimeUtil::SECONDS_PER_DAY;
591 this->doy--;
592 }
593
594
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)))
595 {
596 this->doy -= InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year));
597 this->year++;
598 }
599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 while (this->doy < 1)
600 {
601 this->doy += InsTimeUtil::DAYS_PER_YEAR + static_cast<int32_t>(InsTimeUtil::isLeapYear(this->year - 1));
602 this->year--;
603 }
604 7 }
605
606 /// @brief Equal comparison operator (takes double precision into account)
607 /// @param[in] rhs Right-hand side to compare with
608 /// @return Comparison result
609 78 constexpr bool operator==(const InsTime_YDoySod& rhs) const
610 {
611
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)
612 {
613 44 return gcem::abs(sod - rhs.sod) <= InsTimeUtil::EPSILON;
614 }
615 68 if (auto diffDays = year * InsTimeUtil::DAYS_PER_YEAR + doy - (rhs.year * InsTimeUtil::DAYS_PER_YEAR + rhs.doy);
616
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 14 times.
34 gcem::abs(diffDays) == 1)
617 {
618 20 auto difference = gcem::abs(sod + diffDays * InsTimeUtil::SECONDS_PER_DAY - rhs.sod);
619 20 return difference <= InsTimeUtil::EPSILON;
620 }
621 14 return false;
622 }
623 /// @brief Inequal comparison operator (takes double precision into account)
624 /// @param[in] rhs Right-hand side to compare with
625 /// @return Comparison result
626 36 constexpr bool operator!=(const InsTime_YDoySod& rhs) const
627 {
628 36 return !(*this == rhs);
629 }
630 /// @brief Smaller or equal comparison operator (takes double precision into account)
631 /// @param[in] rhs Right-hand side to compare with
632 /// @return Comparison result
633 30 constexpr bool operator<=(const InsTime_YDoySod& rhs) const
634 {
635
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;
636 }
637 /// @brief Greater or equal comparison operator (takes double precision into account)
638 /// @param[in] rhs Right-hand side to compare with
639 /// @return Comparison result
640 12 constexpr bool operator>=(const InsTime_YDoySod& rhs) const
641 {
642
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;
643 }
644 /// @brief Smaller comparison operator (takes double precision into account)
645 /// @param[in] rhs Right-hand side to compare with
646 /// @return Comparison result
647 36 constexpr bool operator<(const InsTime_YDoySod& rhs) const
648 {
649 36 return (year < rhs.year
650
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)
651
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))
652
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
64 && *this != rhs;
653 }
654 /// @brief Greater comparison operator (takes double precision into account)
655 /// @param[in] rhs Right-hand side to compare with
656 /// @return Comparison result
657 18 constexpr bool operator>(const InsTime_YDoySod& rhs) const
658 {
659 18 return !(*this <= rhs);
660 }
661
662 /// @brief Converts the object into a readable string
663 explicit operator std::string() const;
664 };
665
666 /// The class is responsible for all time-related tasks
667 class InsTime
668 {
669 public:
670 /* ------------------------------ Constructors ------------------------------ */
671
672 /// @brief Default Constructor
673 480886 constexpr InsTime() = default;
674
675 /// @brief Constructor
676 /// @param[in] mjd Time in Modified Julien Date
677 /// @param[in] timesys Time System in which the previous values are given in
678 32 constexpr explicit InsTime(const InsTime_MJD& mjd, TimeSystem timesys = UTC)
679 32 : _mjd(mjd)
680 {
681
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));
682 32 }
683
684 /// @brief Constructor
685 /// @param[in] jd Time in Julien Date
686 /// @param[in] timesys Time System in which the previous values are given in
687 192778 constexpr explicit InsTime(const InsTime_JD& jd, TimeSystem timesys = UTC)
688 192778 : _mjd(jd.jd_day - InsTimeUtil::DIFF_MJD_TO_JD_DAYS, jd.jd_frac - InsTimeUtil::DIFF_MJD_TO_JD_FRAC)
689 {
690
2/4
✓ Branch 1 taken 192772 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 192774 times.
✗ Branch 6 not taken.
192779 *this -= std::chrono::duration<long double>(differenceToUTC(timesys));
691 192774 }
692
693 /// @brief Constructor
694 /// @param[in] gpsWeekTow Time as week and time of week
695 /// @param[in] timesys Time System in which the previous values are given in
696 101113 constexpr explicit InsTime(const InsTime_GPSweekTow& gpsWeekTow, TimeSystem timesys = GPST)
697 101113 {
698 101102 auto mjd_day = static_cast<int32_t>((gpsWeekTow.gpsCycle * InsTimeUtil::WEEKS_PER_GPS_CYCLE + gpsWeekTow.gpsWeek) * InsTimeUtil::DAYS_PER_WEEK
699 101102 + gcem::floor(gpsWeekTow.tow / InsTimeUtil::SECONDS_PER_DAY)
700 101081 + InsTimeUtil::DIFF_TO_6_1_1980_MJD);
701 101081 long double mjd_frac = gcem::fmod(gpsWeekTow.tow, InsTimeUtil::SECONDS_PER_DAY) / InsTimeUtil::SECONDS_PER_DAY;
702
703 101095 _mjd = InsTime_MJD(mjd_day, mjd_frac);
704
705
2/4
✓ Branch 1 taken 101075 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 101054 times.
✗ Branch 6 not taken.
101095 *this -= std::chrono::duration<long double>(differenceToUTC(timesys));
706 101054 }
707
708 /// @brief Constructor
709 /// @param[in] yearMonthDayHMS Time in Universal Time Coordinated
710 /// @param[in] timesys Time System in which the previous values are given in
711 192763 constexpr explicit InsTime(const InsTime_YMDHMS& yearMonthDayHMS, TimeSystem timesys = UTC)
712 192763 {
713 192748 auto a = static_cast<int32_t>((14 - yearMonthDayHMS.month) / static_cast<double>(InsTimeUtil::MONTHS_PER_YEAR));
714 192748 int32_t y = yearMonthDayHMS.year + 4800 - a;
715 192748 int32_t m = yearMonthDayHMS.month + InsTimeUtil::MONTHS_PER_YEAR * a - 3;
716
717 192748 auto jd_day = static_cast<int32_t>(yearMonthDayHMS.day
718 192748 + gcem::floor((153.0 * static_cast<double>(m) + 2.0) / 5.0)
719 192747 + y * InsTimeUtil::DAYS_PER_YEAR
720 192747 + gcem::floor(static_cast<double>(y) / 4.0)
721 192753 - gcem::floor(static_cast<double>(y) / 100.0)
722 192761 + gcem::floor(static_cast<double>(y) / 400.0)
723 192761 - 32045);
724 192761 auto jd_frac = (yearMonthDayHMS.sec
725 192761 + static_cast<long double>(yearMonthDayHMS.min) * InsTimeUtil::SECONDS_PER_MINUTE
726 192761 + static_cast<long double>(yearMonthDayHMS.hour - 12.0) * InsTimeUtil::SECONDS_PER_HOUR)
727 / InsTimeUtil::SECONDS_PER_DAY;
728
729
2/4
✓ Branch 3 taken 192751 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 192756 times.
✗ Branch 8 not taken.
192761 _mjd = InsTime(InsTime_JD(jd_day, jd_frac)).toMJD();
730
731
2/4
✓ Branch 1 taken 192763 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 192761 times.
✗ Branch 6 not taken.
192756 *this -= std::chrono::duration<long double>(differenceToUTC(timesys));
732 192761 }
733
734 /// @brief Constructor
735 /// @param[in] yearDoySod Time as Year, day of year and seconds of day
736 /// @param[in] timesys Time System in which the previous values are given in
737 28 constexpr explicit InsTime(const InsTime_YDoySod& yearDoySod, TimeSystem timesys = UTC)
738 28 {
739 28 auto year = yearDoySod.year;
740 28 auto doy = yearDoySod.doy;
741 28 auto sod = yearDoySod.sod;
742
743 28 int32_t month = 1;
744
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 28 times.
62 while (doy > InsTimeUtil::daysInMonth(month, year))
745 {
746 34 doy -= InsTimeUtil::daysInMonth(month, year);
747 34 month++;
748 }
749
750
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();
751
752
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));
753 28 }
754
755 /// @brief Constructor
756 /// @param[in] gpsCycle GPS cycle in GPS standard time
757 /// @param[in] gpsWeek GPS week in GPS standard time
758 /// @param[in] tow GPS time of week in GPS standard time
759 /// @param[in] timesys Time System in which the previous values are given in
760 72591 constexpr InsTime(int32_t gpsCycle, int32_t gpsWeek, long double tow, TimeSystem timesys = GPST)
761
1/2
✓ Branch 2 taken 72592 times.
✗ Branch 3 not taken.
72591 : InsTime(InsTime_GPSweekTow(gpsCycle, gpsWeek, tow), timesys) {}
762
763 /// @brief Constructor
764 /// @param[in] year Year
765 /// @param[in] month Month (1 = January)
766 /// @param[in] day Day (1 = first day)
767 /// @param[in] hour Hour
768 /// @param[in] min Minute
769 /// @param[in] sec Second
770 /// @param[in] timesys Time System in which the previous values are given in
771 192684 constexpr InsTime(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, long double sec, TimeSystem timesys = UTC)
772
2/4
✓ Branch 1 taken 192685 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 192694 times.
✗ Branch 5 not taken.
192684 : InsTime(InsTime_YMDHMS(year, month, day, hour, min, sec), timesys) {}
773
774 /// @brief Destructor
775 ~InsTime() = default;
776 /// @brief Copy constructor
777 constexpr InsTime(const InsTime&) = default;
778 /// @brief Move constructor
779 constexpr InsTime(InsTime&&) = default;
780 /// @brief Copy assignment operator
781 constexpr InsTime& operator=(const InsTime&) = default;
782 /// @brief Move assignment operator
783 constexpr InsTime& operator=(InsTime&&) = default;
784
785 /* ------------------------ Transformation functions ------------------------ */
786
787 /// @brief Converts this time object into a different format
788 /// @param timesys Time System in which the time should be given
789 /// @return InsTime_MJD structure of the this object
790 236661 [[nodiscard]] constexpr InsTime_MJD toMJD(TimeSystem timesys = UTC) const
791 {
792 236661 long double mjdFrac = _mjd.mjd_frac + static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY);
793 236669 return { _mjd.mjd_day, mjdFrac };
794 }
795
796 /// @brief Converts this time object into a different format
797 /// @param timesys Time System in which the time should be given
798 /// @return InsTime_JD structure of the this object
799 39626 [[nodiscard]] constexpr InsTime_JD toJD(TimeSystem timesys = UTC) const
800 {
801 39626 auto jd_day = _mjd.mjd_day + InsTimeUtil::DIFF_MJD_TO_JD_DAYS;
802 39626 auto jd_frac = _mjd.mjd_frac + InsTimeUtil::DIFF_MJD_TO_JD_FRAC;
803
804 39626 jd_frac += static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY);
805
806 39626 return { jd_day, jd_frac };
807 }
808
809 /// @brief Converts this time object into a different format
810 /// @param timesys Time System in which the time should be given
811 /// @return InsTime_GPSweekTow structure of the this object
812 139341 [[nodiscard]] constexpr InsTime_GPSweekTow toGPSweekTow(TimeSystem timesys = GPST) const
813 {
814 139341 InsTime_MJD mjd_leap = _mjd;
815 // Convert from UTC to intended time system
816
1/2
✓ Branch 1 taken 139342 times.
✗ Branch 2 not taken.
139341 mjd_leap.mjd_frac += static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY);
817
818 // Put everything in the time of week, as it gets splitted in InsTime_GPSweekTow constructor
819 139342 auto tow = static_cast<long double>((mjd_leap.mjd_day - InsTimeUtil::DIFF_TO_6_1_1980_MJD)) * InsTimeUtil::SECONDS_PER_DAY
820 139342 + mjd_leap.mjd_frac * InsTimeUtil::SECONDS_PER_DAY;
821
822 278684 return { 0, 0, tow };
823 }
824
825 /// @brief Converts this time object into a different format
826 /// @param timesys Time System in which the time should be given
827 /// @param digits Amount of digits for the seconds to round to
828 /// @return InsTime_YMDHMS structure of the this object
829 39623 [[nodiscard]] constexpr InsTime_YMDHMS toYMDHMS(TimeSystem timesys = UTC, int digits = -1) const
830 {
831 // transform MJD to JD
832
1/2
✓ Branch 2 taken 39623 times.
✗ Branch 3 not taken.
39623 InsTime_JD jd = toJD();
833 39623 jd.jd_frac = jd.jd_frac + 0.5L;
834
1/2
✓ Branch 1 taken 39623 times.
✗ Branch 2 not taken.
39623 jd.jd_frac += static_cast<long double>(differenceToUTC(timesys)) / static_cast<long double>(InsTimeUtil::SECONDS_PER_DAY);
835
2/2
✓ Branch 0 taken 28981 times.
✓ Branch 1 taken 10642 times.
39623 if (jd.jd_frac >= 1.0L)
836 {
837 28981 jd.jd_day += static_cast<int32_t>(jd.jd_frac);
838 28981 jd.jd_frac -= gcem::floor(jd.jd_frac);
839 }
840 // transform JD to YMDHMS
841 39623 double a = 32044.0 + jd.jd_day;
842 39623 double b = gcem::floor((4.0 * a + 3.0) / 146097.0);
843 39623 double c = a - gcem::floor((b * 146097.0) / 4.0);
844
845 39623 double d = gcem::floor((4.0 * c + 3.0) / 1461.0);
846 39623 double e = c - gcem::floor((1461.0 * d) / 4.0);
847 39623 double m = gcem::floor((5.0 * e + 2.0) / 153.0);
848
849 39623 auto day = static_cast<uint16_t>(e - gcem::floor((153.0 * m + 2.0) / 5.0) + 1);
850 39623 auto month = static_cast<uint16_t>(m + 3 - 12 * gcem::floor(m / 10.0));
851 39623 auto year = static_cast<uint16_t>(b * 100 + d - 4800.0 + gcem::floor(m / 10.0));
852
853 39623 long double sec = jd.jd_frac * InsTimeUtil::SECONDS_PER_DAY;
854
855
1/2
✓ Branch 1 taken 39623 times.
✗ Branch 2 not taken.
79246 return { year, month, day, 0, 0, sec, digits };
856 }
857
858 /// @brief Converts this time object into a different format
859 /// @param timesys Time System in which the time should be given
860 /// @return InsTime_YDoySod structure of the this object
861 4 [[nodiscard]] constexpr InsTime_YDoySod toYDoySod(TimeSystem timesys = UTC) const
862 {
863
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 InsTime_YMDHMS yearMonthDayHMS = toYMDHMS();
864
865 4 auto year = yearMonthDayHMS.year;
866 4 long double sod = static_cast<long double>(yearMonthDayHMS.hour * InsTimeUtil::SECONDS_PER_HOUR
867 4 + yearMonthDayHMS.min * InsTimeUtil::SECONDS_PER_MINUTE)
868 4 + yearMonthDayHMS.sec
869
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 + static_cast<long double>(differenceToUTC(timesys));
870
871 4 int32_t doy = 0;
872
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
18 for (int32_t i = 1; i < yearMonthDayHMS.month; i++)
873 {
874 14 doy += InsTimeUtil::daysInMonth(i, year);
875 }
876 4 doy += yearMonthDayHMS.day;
877
878 8 return { year, doy, sod };
879 }
880
881 /// @brief Returns the current time rounded/cutted to a full day (changes time to 0:0:0h UTC of current day)
882 /// @return The rounded/cutted time object
883 [[nodiscard]] constexpr InsTime toFullDay() const
884 {
885 return InsTime(InsTime_MJD(_mjd.mjd_day, 0.0L));
886 }
887
888 /// @brief Converts this time object into a UNIX timestamp in [s]
889 /// @attention Do not pass `long double` to the LOG_... functions, it can loop indefinitely
890 4 [[nodiscard]] constexpr long double toUnixTime() const
891 {
892 4 return static_cast<long double>((_mjd.mjd_day - InsTimeUtil::DIFF_TO_1_1_1970_MJD) * InsTimeUtil::SECONDS_PER_DAY)
893 4 + _mjd.mjd_frac * InsTimeUtil::SECONDS_PER_DAY;
894 }
895
896 /* ----------------------------- Leap functions ----------------------------- */
897
898 /// @brief Returns the current number of leap seconds (offset GPST to UTC)
899 /// @return Number of leap seconds
900 466020 [[nodiscard]] constexpr uint16_t leapGps2UTC() const
901 {
902 466020 return leapGps2UTC(_mjd);
903 }
904
905 /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime object
906 /// @param[in] insTime Time point
907 /// @return Number of leap seconds
908 7 static constexpr uint16_t leapGps2UTC(const InsTime& insTime)
909 {
910 7 return leapGps2UTC(insTime._mjd);
911 }
912
913 /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_GPSweekTow object
914 /// @param[in] gpsWeekTow Time point
915 /// @return Number of leap seconds
916 1 static constexpr uint16_t leapGps2UTC(const InsTime_GPSweekTow& gpsWeekTow)
917 {
918
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());
919 }
920
921 /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_YDoySod object
922 /// @param[in] yearDoySod Time point
923 /// @return Number of leap seconds
924 1 static constexpr uint16_t leapGps2UTC(const InsTime_YDoySod& yearDoySod)
925 {
926
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());
927 }
928
929 /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_YMDHMS object
930 /// @param[in] yearMonthDayHMS Time point
931 /// @return Number of leap seconds
932 1 static constexpr uint16_t leapGps2UTC(const InsTime_YMDHMS& yearMonthDayHMS)
933 {
934
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());
935 }
936
937 /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_JD object
938 /// @param[in] jd Time point
939 /// @return Number of leap seconds
940 1 static constexpr uint16_t leapGps2UTC(const InsTime_JD& jd)
941 {
942
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());
943 }
944
945 /// @brief Returns the number of leap seconds (offset GPST to UTC) for the provided InsTime_MJD object
946 /// @param[in] mjd_in Time point
947 /// @return Number of leap seconds
948 466026 static constexpr uint16_t leapGps2UTC(const InsTime_MJD& mjd_in)
949 {
950 466026 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);
951 }
952
953 /// @brief Checks if the current time is a leap year
954 /// @return True if the current time is a leap year, false otherwise
955 1 [[nodiscard]] constexpr bool isLeapYear() const
956 {
957
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return InsTimeUtil::isLeapYear(toYMDHMS().year);
958 }
959
960 /* --------------------- Comparison operator overloading -------------------- */
961
962 /// @brief Equal comparison operator (takes double precision into account)
963 /// @param[in] rhs Right-hand side to compare with
964 /// @return Comparison result
965 7049138 constexpr bool operator==(const InsTime& rhs) const { return _mjd == rhs._mjd; }
966 /// @brief Inequal comparison operator (takes double precision into account)
967 /// @param[in] rhs Right-hand side to compare with
968 /// @return Comparison result
969 50047 constexpr bool operator!=(const InsTime& rhs) const { return !(*this == rhs); }
970 /// @brief Smaller or equal comparison operator (takes double precision into account)
971 /// @param[in] rhs Right-hand side to compare with
972 /// @return Comparison result
973
4/4
✓ Branch 1 taken 10266 times.
✓ Branch 2 taken 24627 times.
✓ Branch 4 taken 10072 times.
✓ Branch 5 taken 194 times.
34893 constexpr bool operator<=(const InsTime& rhs) const { return *this < rhs || *this == rhs; }
974 /// @brief Greater or equal comparison operator (takes double precision into account)
975 /// @param[in] rhs Right-hand side to compare with
976 /// @return Comparison result
977
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; }
978 /// @brief Smaller comparison operator (takes double precision into account)
979 /// @param[in] rhs Right-hand side to compare with
980 /// @return Comparison result
981 1067570 constexpr bool operator<(const InsTime& rhs) const { return _mjd < rhs._mjd; }
982 /// @brief Greater comparison operator (takes double precision into account)
983 /// @param[in] rhs Right-hand side to compare with
984 /// @return Comparison result
985 27568 constexpr bool operator>(const InsTime& rhs) const { return !(*this <= rhs); }
986
987 /* --------------------- Arithmetic operator overloading -------------------- */
988
989 /// @brief Substracts 2 points in time
990 /// @param[in] lhs The left hand side time point
991 /// @param[in] rhs The right hand side time point
992 /// @return Time difference in [seconds]
993 1645875 constexpr friend std::chrono::duration<long double> operator-(const InsTime& lhs, const InsTime& rhs)
994 {
995 1645875 auto diffDays = lhs._mjd.mjd_day - rhs._mjd.mjd_day;
996 1645875 auto diffFrac = lhs._mjd.mjd_frac - rhs._mjd.mjd_frac;
997 1645875 long double diffSec = (diffFrac + static_cast<long double>(diffDays)) * InsTimeUtil::SECONDS_PER_DAY;
998 1645875 return std::chrono::duration<long double>(diffSec);
999 }
1000
1001 /// @brief Adds a duration to this time point
1002 /// @param[in] duration The duration to add
1003 /// @return Reference to this object
1004 201715 constexpr InsTime& operator+=(const std::chrono::duration<long double>& duration)
1005 {
1006
1/2
✓ Branch 1 taken 201721 times.
✗ Branch 2 not taken.
201715 auto duration_mjd_frac = std::chrono::duration<long double, std::ratio<InsTimeUtil::SECONDS_PER_DAY>>(duration).count();
1007 403442 this->_mjd = InsTime_MJD(this->_mjd.mjd_day,
1008 201716 this->_mjd.mjd_frac + duration_mjd_frac);
1009 201726 return *this;
1010 }
1011
1012 /// @brief Substracts a duration to this time point
1013 /// @param[in] duration The duration to substract
1014 /// @return Reference to this object
1015 660315 constexpr InsTime& operator-=(const std::chrono::duration<long double>& duration)
1016 {
1017
1/2
✓ Branch 1 taken 660281 times.
✗ Branch 2 not taken.
660315 auto duration_mjd_frac = std::chrono::duration<long double, std::ratio<InsTimeUtil::SECONDS_PER_DAY>>(duration).count();
1018 1320574 this->_mjd = InsTime_MJD(this->_mjd.mjd_day,
1019 660260 this->_mjd.mjd_frac - duration_mjd_frac);
1020 660314 return *this;
1021 }
1022
1023 /// @brief Adds a duration to a time point
1024 /// @param[in] time The left hand side time point
1025 /// @param[in] duration The right hand side duration
1026 /// @return Time point with the added duration
1027 200747 constexpr friend InsTime operator+(const InsTime& time, const std::chrono::duration<long double>& duration)
1028 {
1029
1/2
✓ Branch 1 taken 200759 times.
✗ Branch 2 not taken.
200747 return InsTime(time) += duration;
1030 }
1031
1032 /// @brief Substracts a duration from a time point
1033 /// @param[in] time The left hand side time point
1034 /// @param[in] duration The right hand side duration
1035 /// @return Time point with the substracted duration
1036 173642 constexpr friend InsTime operator-(const InsTime& time, const std::chrono::duration<long double>& duration)
1037 {
1038
1/2
✓ Branch 1 taken 173642 times.
✗ Branch 2 not taken.
173642 return InsTime(time) -= duration;
1039 }
1040
1041 /* ---------------------------- Utility Functions --------------------------- */
1042
1043 /// @brief Converts the object into a readable string
1044 explicit operator std::string() const;
1045
1046 /// @brief Checks if the Time object has a value
1047 2598259 [[nodiscard]] constexpr bool empty() const
1048 {
1049
4/4
✓ Branch 0 taken 481056 times.
✓ Branch 1 taken 2117203 times.
✓ Branch 2 taken 481011 times.
✓ Branch 3 taken 45 times.
2598259 return _mjd.mjd_day == 0 && _mjd.mjd_frac == 0.0L;
1050 }
1051
1052 /// @brief Resets the InsTime object
1053 220417 void reset()
1054 {
1055 220417 _mjd.mjd_day = 0;
1056 220417 _mjd.mjd_frac = 0.0L;
1057 220417 }
1058
1059 /// @brief Adds the difference [seconds] between toe (OBRIT-0 last element) and toc (ORBIT-0 first element) to the current time
1060 /// (Changes time, so that it corresponds to the time of GLONASS ORBIT last element)
1061 /// @param[in] UTC_sec Seconds in UTC time
1062 void MakeTimeFromGloOrbit(double UTC_sec)
1063 {
1064 auto ymdhms = toYMDHMS();
1065 // difference between toe (OBRIT-0 last element) and toc (ORBIT-0 first element) in seconds
1066 long double diff = gcem::fmod(static_cast<long double>(UTC_sec), InsTimeUtil::SECONDS_PER_DAY)
1067 - (ymdhms.hour * InsTimeUtil::SECONDS_PER_HOUR
1068 + ymdhms.min * InsTimeUtil::SECONDS_PER_MINUTE
1069 + ymdhms.sec);
1070 // std::cout << "orbit diff " << diff << "\n";
1071 *this += std::chrono::duration<long double>(diff);
1072 }
1073
1074 /// @brief Returns the time difference in [s] of a time system and UTC
1075 /// @param[in] timesys Time system to get the difference from UTC
1076 942034 [[nodiscard]] constexpr int differenceToUTC(TimeSystem timesys) const
1077 {
1078
7/8
✓ Branch 1 taken 398748 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 22882 times.
✓ Branch 4 taken 2172 times.
✓ Branch 5 taken 54 times.
✓ Branch 6 taken 20160 times.
✓ Branch 7 taken 497984 times.
✗ Branch 8 not taken.
942034 switch (TimeSystem_(timesys))
1079 {
1080 398748 case GPST: // = GPS Time (UTC + leap_seconds)
1081 398748 return this->leapGps2UTC();
1082 17 case GLNT: // = GLONASS Time (UTC+ 3h)
1083 17 return 3 * InsTimeUtil::SECONDS_PER_HOUR;
1084 22882 case GST: // = GALILEO Time (~ GPS) (UTC = GST - 18) is synchronized with TAI with a nominal offset below 50 ns
1085 22882 return this->leapGps2UTC();
1086 2172 case QZSST:
1087 2172 return this->leapGps2UTC(); // TODO citation for synchronization accuracy
1088 54 case IRNSST:
1089 54 return this->leapGps2UTC(); // TODO citation for synchronization accuracy
1090 20160 case BDT: // = BeiDou Time (UTC) is synchronized with UTC within 100 ns<
1091 20160 return this->leapGps2UTC() - 14;
1092 497984 case UTC:
1093 case TimeSys_None:
1094 497984 return 0;
1095 }
1096 return 0;
1097 }
1098
1099 private:
1100 /// @brief Modified Julien Date of this InsTime object
1101 InsTime_MJD _mjd;
1102 };
1103
1104 /// @brief Stream insertion operator overload
1105 /// @param[in, out] os Output stream object to stream the time into
1106 /// @param[in] mjd Object to print
1107 /// @return Returns the output stream object in order to chain stream insertions
1108 std::ostream& operator<<(std::ostream& os, const InsTime_MJD& mjd);
1109 /// @brief Stream insertion operator overload
1110 /// @param[in, out] os Output stream object to stream the time into
1111 /// @param[in] jd Object to print
1112 /// @return Returns the output stream object in order to chain stream insertions
1113 std::ostream& operator<<(std::ostream& os, const InsTime_JD& jd);
1114 /// @brief Stream insertion operator overload
1115 /// @param[in, out] os Output stream object to stream the time into
1116 /// @param[in] gpsWeekTow Object to print
1117 /// @return Returns the output stream object in order to chain stream insertions
1118 std::ostream& operator<<(std::ostream& os, const InsTime_GPSweekTow& gpsWeekTow);
1119 /// @brief Stream insertion operator overload
1120 /// @param[in, out] os Output stream object to stream the time into
1121 /// @param[in] ymdhms Object to print
1122 /// @return Returns the output stream object in order to chain stream insertions
1123 std::ostream& operator<<(std::ostream& os, const InsTime_YMDHMS& ymdhms);
1124 /// @brief Stream insertion operator overload
1125 /// @param[in, out] os Output stream object to stream the time into
1126 /// @param[in] yDoySod Object to print
1127 /// @return Returns the output stream object in order to chain stream insertions
1128 std::ostream& operator<<(std::ostream& os, const InsTime_YDoySod& yDoySod);
1129 /// @brief Stream insertion operator overload
1130 /// @param[in, out] os Output stream object to stream the time into
1131 /// @param[in] insTime Object to print
1132 /// @return Returns the output stream object in order to chain stream insertions
1133 std::ostream& operator<<(std::ostream& os, const InsTime& insTime);
1134
1135 /// @brief Converts the provided InsTime into a json object
1136 /// @param[out] j Return Json object
1137 /// @param[in] insTime Time to convert
1138 void to_json(json& j, const InsTime& insTime);
1139 /// @brief Converts the provided json object into an InsTime
1140 /// @param[in] j Json object with the time values
1141 /// @param[out] insTime Time to return
1142 void from_json(const json& j, InsTime& insTime);
1143
1144 } // namespace NAV
1145
1146 namespace std
1147 {
1148 /// @brief Hash function for InsTime (needed for unordered_map)
1149 template<>
1150 struct hash<NAV::InsTime>
1151 {
1152 /// @brief Hash function for InsTime
1153 /// @param[in] t Time
1154 std::size_t operator()(const NAV::InsTime& t) const
1155 {
1156 auto hash1 = std::hash<int32_t>{}(t.toMJD().mjd_day);
1157 auto hash2 = std::hash<long double>{}(t.toMJD().mjd_frac);
1158
1159 return hash1 | (hash2 << 32);
1160 }
1161 };
1162 } // namespace std
1163
1164 #ifndef DOXYGEN_IGNORE
1165
1166 /// @brief Formatter
1167 template<>
1168 struct fmt::formatter<NAV::InsTime_MJD> : fmt::formatter<std::string>
1169 {
1170 /// @brief Defines how to format this structs
1171 /// @param[in] mjd Struct to format
1172 /// @param[in, out] ctx Format context
1173 /// @return Output iterator
1174 template<typename FormatContext>
1175 auto format(const NAV::InsTime_MJD& mjd, FormatContext& ctx) const
1176 {
1177 return fmt::format_to(ctx.out(), "day={}, frac={}", mjd.mjd_day, static_cast<double>(mjd.mjd_frac));
1178 }
1179 };
1180 /// @brief Formatter
1181 template<>
1182 struct fmt::formatter<NAV::InsTime_JD> : fmt::formatter<std::string>
1183 {
1184 /// @brief Defines how to format this structs
1185 /// @param[in] jd Struct to format
1186 /// @param[in, out] ctx Format context
1187 /// @return Output iterator
1188 template<typename FormatContext>
1189 auto format(const NAV::InsTime_JD& jd, FormatContext& ctx) const
1190 {
1191 return fmt::format_to(ctx.out(), "day={}, frac={}", jd.jd_day, static_cast<double>(jd.jd_frac));
1192 }
1193 };
1194 /// @brief Formatter
1195 template<>
1196 struct fmt::formatter<NAV::InsTime_GPSweekTow> : fmt::formatter<std::string>
1197 {
1198 /// @brief Defines how to format this structs
1199 /// @param[in] gpsWeekTow Struct to format
1200 /// @param[in, out] ctx Format context
1201 /// @return Output iterator
1202 template<typename FormatContext>
1203 19560 auto format(const NAV::InsTime_GPSweekTow& gpsWeekTow, FormatContext& ctx) const
1204 {
1205 39120 return fmt::format_to(ctx.out(), "cycle={}, week={}, tow={}",
1206 39120 gpsWeekTow.gpsCycle, gpsWeekTow.gpsWeek, static_cast<double>(gpsWeekTow.tow));
1207 }
1208 };
1209 /// @brief Formatter
1210 template<>
1211 struct fmt::formatter<NAV::InsTime_YMDHMS> : fmt::formatter<std::string>
1212 {
1213 /// @brief Defines how to format this structs
1214 /// @param[in] ymdhms Struct to format
1215 /// @param[in, out] ctx Format context
1216 /// @return Output iterator
1217 template<typename FormatContext>
1218 37449 auto format(const NAV::InsTime_YMDHMS& ymdhms, FormatContext& ctx) const
1219 {
1220 74898 return fmt::format_to(ctx.out(), "{}-{}-{} {}:{}:{:.6g}",
1221 37449 ymdhms.year, ymdhms.month, ymdhms.day,
1222 74898 ymdhms.hour, ymdhms.min, static_cast<double>(ymdhms.sec));
1223 }
1224 };
1225 /// @brief Formatter
1226 template<>
1227 struct fmt::formatter<NAV::InsTime_YDoySod> : fmt::formatter<std::string>
1228 {
1229 /// @brief Defines how to format this structs
1230 /// @param[in] yDoySod Struct to format
1231 /// @param[in, out] ctx Format context
1232 /// @return Output iterator
1233 template<typename FormatContext>
1234 auto format(const NAV::InsTime_YDoySod& yDoySod, FormatContext& ctx) const
1235 {
1236 return fmt::format_to(ctx.out(), "year={}, doy={}, sod={:.6g}",
1237 yDoySod.year, yDoySod.doy, static_cast<double>(yDoySod.sod));
1238 }
1239 };
1240 /// @brief Formatter
1241 template<>
1242 struct fmt::formatter<NAV::InsTime> : fmt::formatter<std::string>
1243 {
1244 /// @brief Defines how to format this structs
1245 /// @param[in] insTime Struct to format
1246 /// @param[in, out] ctx Format context
1247 /// @return Output iterator
1248 template<typename FormatContext>
1249 12902 auto format(const NAV::InsTime& insTime, FormatContext& ctx) const
1250 {
1251
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());
1252 }
1253 };
1254
1255 #endif
1256