Created on 2024-07-26.00:00:00 last changed 1 month ago
Proposed resolution:
This wording is relative to N4986.
Modify [time.format] as indicated:
template<classDuration, class charT> struct formatter<chrono::local-time-format-t<Duration>, charT>;-17- Let `f` be a
locale-time-format-t<Duration>
object passed to `formatter::format`.-18- Remarks: If the chrono-specs is omitted, the result is equivalent to using `%F %T %Z` as the chrono-specs. If `%Z` is used, it is replaced with `*f.abbrev` if `f.abbrev` is not a null pointer value. If `%Z` is used and `f.abbrev` is a null pointer value, an exception of type `format_error` is thrown. If `%z` (or a modified variant of `%z`) is used, it is formatted with the value of `*f.offset_sec` if `f.offset_sec` is not a null pointer value. If `%z` (or a modified variant of `%z`) is used and `f.offset_sec` is a null pointer value, then an exception of type `format_error` is thrown.
template<class Duration, class TimeZonePtr, class charT> struct formatter<chrono::zoned_time<Duration, TimeZonePtr>, charT> : formatter<chrono::local-time-format-t<common_type_t<Duration, seconds>>, charT> { template<class FormatContext> typename FormatContext::iterator format(const chrono::zoned_time<Duration, TimeZonePtr>& tp, FormatContext& ctx) const; };template<class FormatContext> typename FormatContext::iterator format(const chrono::zoned_time<Duration, TimeZonePtr>& tp, FormatContext& ctx) const;-19- Effects: Equivalent to:
sys_info info = tp.get_info(); return formatter<chrono::local-time-format-t<common_type_t<Duration, seconds>>, charT>:: format({tp.get_local_time(), &info.abbrev, &info.offset}, ctx);
[ 2024-08-02; Reflector poll ]
Set status to Tentatively Ready after seven votes in favour during reflector poll.
The
std::formatter<std::chrono::zoned_time<Duration, TimeZonePtr>>
specialization calls `tp.get_local_time()` for the object it passes to its
base class' `format` function. But `get_local_time()` does not return a
local_time<Duration>
, it returns
local_time<common_type_t<Duration, seconds>>
.
The base class' `format` function is only defined for
local_time<Duration>
.
That means this is ill-formed, even though the static assert passes:
using namespace std::chrono;
static_assert( std::formattable<zoned_time<minutes>, char> );
zoned_time<minutes> zt;
(void) std::format("{}", zt); // error: cannot convert local_time<seconds> to local_time<minutes>
Additionally, it's not specified what output you should get for:
`std::format("{}", local_time_format(zt.get_local_time()));`
[time.format] p7 says it's formatted as if by streaming to an
`ostringstream`,
but there is no operator<<
for `local-time-format-t`.
Presumably it should give the same result as operator<<
for
a `zoned_time`, i.e. `"{:L%F %T %Z}"` with padding adjustments etc.
The proposed resolution below has been implemented in libstdc++.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-08-02 21:14:41 | admin | set | messages: + msg14278 |
2024-08-02 21:14:41 | admin | set | status: new -> ready |
2024-07-26 21:47:51 | admin | set | messages: + msg14268 |
2024-07-26 00:00:00 | admin | create |