From 591f572b670d27311361b9b6b933cbcfced55560 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Wed, 26 Sep 2018 13:55:37 -0700 Subject: [PATCH] Allow %j to parse and format durations --- include/date/date.h | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/include/date/date.h b/include/date/date.h index 8e1be13..6d1ff7c 100644 --- a/include/date/date.h +++ b/include/date/date.h @@ -5034,16 +5034,29 @@ to_stream(std::basic_ostream& os, const CharT* fmt, { if (modified == CharT{}) { - if (!fds.ymd.ok()) + if (fds.ymd.ok() || fds.has_tod) + { + days doy; + if (fds.ymd.ok()) + { + auto ld = local_days(fds.ymd); + auto y = fds.ymd.year(); + doy = ld - local_days(y/January/1) + days{1}; + } + else + { + doy = duration_cast(fds.tod.to_duration()); + } + save_ostream _(os); + os.fill('0'); + os.flags(std::ios::dec | std::ios::right); + os.width(3); + os << doy.count(); + } + else + { os.setstate(std::ios::failbit); - auto ld = local_days(fds.ymd); - auto y = fds.ymd.year(); - auto doy = ld - local_days(y/January/1) + days{1}; - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(3); - os << doy.count(); + } } else { @@ -6150,7 +6163,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, CONSTDATA int not_a_hour_12_value = 0; CONSTDATA int not_a_minute = not_a_hour; CONSTDATA Duration not_a_second = Duration::min(); - CONSTDATA int not_a_doy = 0; + CONSTDATA int not_a_doy = -1; CONSTDATA int not_a_weekday = 8; CONSTDATA int not_a_week_num = 100; CONSTDATA int not_a_ampm = -1; @@ -7317,7 +7330,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, goto broken; computed = true; } - if (j != 0 && Y != not_a_year) + if (j != not_a_doy && Y != not_a_year) { auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; if (m == 0) @@ -7328,6 +7341,7 @@ from_stream(std::basic_istream& is, const CharT* fmt, d = static_cast(static_cast(ymd_trial.day())); else if (day(static_cast(d)) != ymd_trial.day()) goto broken; + j = not_a_doy; } auto ymd = year{Y}/m/d; if (ymd.ok()) @@ -7426,6 +7440,11 @@ from_stream(std::basic_istream& is, const CharT* fmt, fds.has_tod = true; fds.tod.s_ = detail::decimal_format_seconds{s}; } + if (j != not_a_doy) + { + fds.has_tod = true; + fds.tod.h_ += hours{days{j}}; + } if (wd != not_a_weekday) fds.wd = weekday{static_cast(wd)}; if (abbrev != nullptr)