libstdc++: Fix std::format output for std::chrono::zoned_time
When formatting a chrono::zoned_time with an empty chrono-specs, we were
only formatting its _M_time member, but the ostream insertion operator
uses the format "{:L%F %T %Z}" which includes the time zone
abbreviation. The %Z should also be used when formatting with an empty
chrono-specs.
This commit makes _M_format_to_ostream handle __local_time_fmt
specializations directly, rather than calling itself recursively to
format the _M_time member. We need to be able to customize the output of
_M_format_to_ostream for __local_time_fmt, because we use that type for
gps_time and tai_time as well as for zoned_time and __local_time_fmt.
When formatting gps_time and tai_time we don't want to include the time
zone abbreviation in the "{}" output, but for zoned_time we do want to.
We can reuse the __is_neg flag passed to _M_format_to_ostream (via
_M_format) to say that we want the time zone abbreviation. Currently
the __is_neg flag is only used for duration specializations, so it's
available for __local_time_fmt to use.
In addition to fixing the zoned_time output to use %Z, this commit also
changes the __local_time_fmt output to use %Z. Previously it didn't use
it, just like zoned_time. The standard doesn't actually say how to
format local-time-format-t for an empty chrono-specs, but this behaviour
seems sensible and is what I'm proposing as part of LWG 4124.
While testing this I noticed that some chrono types were not being
tested with empty chrono-specs, so this adds more tests. I also noticed
that std/time/clock/local/io.cc was testing tai_time instead of
local_time, which was completely wrong. That's fixed now too.
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (__local_fmt_t): Remove unused
declaration.
(__formatter_chrono::_M_format_to_ostream): Add explicit
handling for specializations of __local_time_fmt, including the
time zone abbreviation in the output if __is_neg is true.
(formatter<chrono::tai_time<D>>::format): Add comment.
(formatter<chrono::gps_time<D>>::format): Likewise.
(formatter<chrono::__detail::__local_time_fmt::format): Call
_M_format with true for the __is_neg flag.
* testsuite/std/time/clock/gps/io.cc: Remove unused variable.
* testsuite/std/time/clock/local/io.cc: Fix test error that
checked tai_time instead of local_time. Add tests for
local-time-format-t formatting.
* testsuite/std/time/clock/system/io.cc: Check empty
chrono-specs.
* testsuite/std/time/clock/tai/io.cc: Likewise.
* testsuite/std/time/zoned_time/io.cc: Likewise.