From e1aa4837e0adb6b426672a87fcd85690d6600531 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Tue, 31 Aug 2021 17:42:18 -0400 Subject: [PATCH] Avoid signed integral overflow in to_stream Fixes: #696 --- include/date/date.h | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/include/date/date.h b/include/date/date.h index bb226ca..3b8b461 100644 --- a/include/date/date.h +++ b/include/date/date.h @@ -6213,8 +6213,13 @@ to_stream(std::basic_ostream& os, const CharT* fmt, const std::chrono::seconds* offset_sec = nullptr) { using CT = typename std::common_type::type; - auto ld = floor(tp); - fields fds{year_month_day{ld}, hh_mm_ss{tp-local_seconds{ld}}}; + auto ld = std::chrono::time_point_cast(tp); + fields fds; + if (ld <= tp) + fds = fields{year_month_day{ld}, hh_mm_ss{tp-local_seconds{ld}}}; + else + fds = fields{year_month_day{ld - days{1}}, + hh_mm_ss{days{1} - (local_seconds{ld} - tp)}}; return to_stream(os, fmt, fds, abbrev, offset_sec); } @@ -6227,8 +6232,13 @@ to_stream(std::basic_ostream& os, const CharT* fmt, using CT = typename std::common_type::type; const std::string abbrev("UTC"); CONSTDATA seconds offset{0}; - auto sd = floor(tp); - fields fds{year_month_day{sd}, hh_mm_ss{tp-sys_seconds{sd}}}; + auto sd = std::chrono::time_point_cast(tp); + fields fds; + if (sd <= tp) + fds = fields{year_month_day{sd}, hh_mm_ss{tp-sys_seconds{sd}}}; + else + fds = fields{year_month_day{sd - days{1}}, + hh_mm_ss{days{1} - (sys_seconds{sd} - tp)}}; return to_stream(os, fmt, fds, &abbrev, &offset); }