Allow %j to parse and format durations

This commit is contained in:
Howard Hinnant
2018-09-26 13:55:37 -07:00
parent 69e9cd612f
commit 591f572b67

View File

@@ -5034,16 +5034,29 @@ to_stream(std::basic_ostream<CharT, Traits>& 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<days>(fds.tod.to_duration());
}
save_ostream<CharT, Traits> _(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<CharT, Traits> _(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<CharT, Traits>& 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<CharT, Traits>& 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<CharT, Traits>& is, const CharT* fmt,
d = static_cast<int>(static_cast<unsigned>(ymd_trial.day()));
else if (day(static_cast<unsigned>(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<CharT, Traits>& is, const CharT* fmt,
fds.has_tod = true;
fds.tod.s_ = detail::decimal_format_seconds<Duration>{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<unsigned>(wd)};
if (abbrev != nullptr)