|
34 | 34 | #include <chrono> |
35 | 35 | #include <cstddef> |
36 | 36 | #include <cstdint> |
| 37 | +#include <ratio> |
37 | 38 | #include <stdexcept> |
38 | 39 | #include <type_traits> |
39 | 40 |
|
@@ -82,6 +83,12 @@ constexpr int32_t abs(int32_t value) noexcept { |
82 | 83 | return value >= 0 ? value : -value; |
83 | 84 | } |
84 | 85 |
|
| 86 | +// NOLINTNEXTLINE |
| 87 | +constexpr auto pow(int32_t base, int32_t exp) noexcept -> int32_t { |
| 88 | + // NOLINTNEXTLINE |
| 89 | + return exp < 0 ? 0 : exp == 0 ? 1 : base * pow(base, exp - 1); |
| 90 | +} |
| 91 | + |
85 | 92 | /** |
86 | 93 | * @brief Checks if a value is within a given range. |
87 | 94 | * |
@@ -320,11 +327,17 @@ MGUTILITY_CNSTXPR auto parse_second(detail::tm &result, string_view date_str, |
320 | 327 |
|
321 | 328 | MGUTILITY_CNSTXPR auto parse_fraction(detail::tm &result, string_view date_str, |
322 | 329 | uint32_t &next) -> std::errc { |
323 | | - auto error = parse_integer(result.tm_ms, date_str, 3, next); |
| 330 | + int32_t digits = 0; |
| 331 | + while (next + digits < date_str.size() && |
| 332 | + mgutility::detail::is_digit(date_str[next + digits]) && digits < 9) { |
| 333 | + ++digits; |
| 334 | + } |
| 335 | + auto error = parse_integer(result.tm_ms, date_str, digits, next); |
324 | 336 | if (error != std::errc{}) { |
325 | 337 | return error; |
326 | 338 | } |
327 | | - error = check_range(result.tm_ms, 0U, 999U); |
| 339 | + result.tm_ms *= static_cast<uint32_t>(pow(10, 9 - digits)); |
| 340 | + error = check_range(result.tm_ms, 0U, 999999999U); |
328 | 341 | return error; |
329 | 342 | } |
330 | 343 |
|
@@ -535,8 +548,7 @@ auto parse(typename Clock::time_point &time_point, string_view format, |
535 | 548 | if (error != std::errc{}) { |
536 | 549 | return std::make_error_code(error); |
537 | 550 | } |
538 | | - time_point = Clock::from_time_t(time_t); |
539 | | - time_point += std::chrono::milliseconds(time_struct.tm_ms); |
| 551 | + time_point = std::chrono::time_point_cast<Clock::duration>(Clock::from_time_t(time_t) + std::chrono::nanoseconds{time_struct.tm_ms}); |
540 | 552 | return std::error_code{}; |
541 | 553 | } |
542 | 554 |
|
|
0 commit comments