https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109162

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #3)
> (In reply to Jonathan Wakely from comment #0)
> > https://wg21.link/P2419R2 localized chrono formatting (also p2372r3)
> 
> I think this this requires using nl_langinfo_l(CODESET, loc) to find out if
> the locale uses UTF-8, and then use iconv to convert to UTF-8 if it doesn't.
> But I'm not sure how we do that for an arbitrary std::locale which doesn't
> have an associated C locale, and we can't get its locale_t identifier anyway.

I remain confused about how to implement this. We could use
newlocale(loc.name()) to try to open a C locale from the C++ locale's name, and
if that works use nl_langinfo_l to get the locale's encoding, then use iconv to
convert to UTF-8.

Libc++ doesn't implement this yet. {fmt} does ... but it seems broken. It uses
std::codecvt<char32_t, char, mbstate_t> to convert the locale's encoding to
UTF-32 and then converts that to UTF-8. But that's wrong. That codecvt
specialization converts between UTF-8 and UTF-32, it's locale-independent. So
the example in P2419 fails with a format_error exception when I run it:

#include <locale>
#include <print>
#include <chrono>
#include <iostream>
#include <fmt/format.h>
#include <fmt/chrono.h>

int main()
{
  std::locale::global(std::locale("ru_UA.koi8u"));
  std::string s = fmt::format("День недели: {:L}", std::chrono::Monday);
  std::cout << s << '\n';
}

terminate called after throwing an instance of 'fmt::v9::format_error'
  what():  failed to format time
Aborted (core dumped)

Reply via email to