1 #include <marnav/nmea/time.hpp>
12 template <class T
> static T
parse_time(const std::string
& str
)
16 double t
= std::stod(str
, &pos
);
17 if (pos
!= str
.size())
18 throw std::invalid_argument
{"invalid format for 'double'"};
20 const uint32_t h
= static_cast<uint32_t>(t
/ 10000) % 100;
21 const uint32_t m
= static_cast<uint32_t>(t
/ 100) % 100;
22 const uint32_t s
= static_cast<uint32_t>(t
) % 100;
23 const uint32_t ms
= static_cast<uint32_t>(t
* 1000) % 1000;
24 return T
{h
, m
, s
, ms
};
25 } catch (std::invalid_argument
&) {
26 throw std::invalid_argument
{"invalid format, 'HHMMSS[.mmm]' expected"};
32 void trait_time::check(uint32_t h
, uint32_t m
, uint32_t s
, uint32_t ms
)
35 throw std::invalid_argument
{"invalid hour in nmea::time"};
37 throw std::invalid_argument
{"invalid minute in nmea::time"};
39 throw std::invalid_argument
{"invalid second in nmea::time"};
41 throw std::invalid_argument
{"invalid milliseconds in nmea::time"};
44 void trait_duration::check(uint32_t h
, uint32_t m
, uint32_t s
, uint32_t ms
)
47 throw std::invalid_argument
{"invalid hour in nmea::duration"};
49 throw std::invalid_argument
{"invalid minute in nmea::duration"};
51 throw std::invalid_argument
{"invalid second in nmea::duration"};
53 throw std::invalid_argument
{"invalid milliseconds in nmea::duration"};
56 /// Parses the time information within the specified string (start and end of string).
57 /// If the string is empty, the result will be initialized to zero.
58 /// The time to be parsed must be in the form: "HHMMSS.mmm" (milliseconds are optional).
59 /// - HH : zero leading hour of the day (00..23)
60 /// - MM : zero leading minute of the hour (00..59)
61 /// - SS : zero leading second of the minute (00..59)
62 /// - mmm : milliseconds (000..999)
64 /// @param[in] str The string to parse.
65 /// @return The parsed time.
66 /// @exception std::invalid_argument Thrown if the string is malformed.
67 time
time::parse(const std::string
& str
)
69 return parse_time
<time
>(str
);
72 /// Returns a string representation in the form 'hhmmss', or ir the specified time has
73 /// milliseconds other than 0, is provides the form 'hhmmss.sss`.
74 std::string
to_string(const time
& t
)
77 if (t
.milliseconds()) {
78 snprintf(buf
, sizeof(buf
), "%02u%02u%02u.%03u", t
.hour(), t
.minutes(), t
.seconds(),
81 snprintf(buf
, sizeof(buf
), "%02u%02u%02u", t
.hour(), t
.minutes(), t
.seconds());
86 /// Returns the data as formatted string.
88 /// @param[in] t The data to format.
89 /// @param[in] width Number of digits for sub-seconds. Since sub-seconds
90 /// are represented as milliseconds in nmea::time, this value can be between 1 and 3.
91 /// If the value is \c 0, the function \c to_string will be used. Values greater
92 /// than 3 are equivalent to 3.
93 std::string
format(const nmea::time
& t
, unsigned int width
)
101 snprintf(fmt
, sizeof(fmt
), "%%02u%%02u%%02u.%%0%uu", width
);
103 for (unsigned int i
= 0; i
< width
; ++i
)
106 snprintf(buf
, sizeof(buf
), fmt
, t
.hour(), t
.minutes(), t
.seconds(), t
.milliseconds() / div
);
110 /// Parses the duration information within the specified string (start and end of string).
111 /// If the string is empty, the result will be initialized to zero.
112 /// The duration to be parsed must be in the form: "HHMMSS.mmm" (milliseconds are optional).
113 /// - HH : zero leading hour of the day (00..99)
114 /// - MM : zero leading minute of the hour (00..59)
115 /// - SS : zero leading second of the minute (00..59)
116 /// - mmm : milliseconds (000..999)
118 /// @param[in] str The string to parse.
119 /// @return The parsed duration
120 /// @exception std::invalid_argument Thrown if the string is malformed.
121 duration
duration::parse(const std::string
& str
)
123 return parse_time
<duration
>(str
);
126 /// Returns a string representation in the form 'hhmmss', does not render fractions of seconds.
127 std::string
to_string(const duration
& d
)
130 snprintf(buf
, sizeof(buf
), "%02u%02u%02u", d
.hour(), d
.minutes(), d
.seconds());