date_time icon indicating copy to clipboard operation
date_time copied to clipboard

Issue in std::basic_string<charT> to_simple_string_type(time_duration td) with locales

Open jalegido opened this issue 3 years ago • 7 comments

There is a problem std::basic_string<charT> to_simple_string_type(time_duration td) if application doesn't use the locale("C").

If you use spanish locale the result of this function is like this one: 2020-11-03T09:26:04.966.395 where the second 'dot' is wrong because is the miles signal in spanish locale.

I propose to correct it, use next code:

std::basic_ostringstream<charT> ss;
ss.imbue(std::locale::classic());

Best regards

jalegido avatar Nov 29 '21 07:11 jalegido

to_simple_string ignores locales, so it's not really the right tool for the job. Have a look at the following:

https://www.boost.org/doc/libs/1_77_0/doc/html/date_time/date_time_io.html#date_time.time_input_facet

https://github.com/boostorg/date_time/blob/develop/test/posix_time/testtime_facet.cpp https://github.com/boostorg/date_time/blob/develop/example/tutorial/io_tutorial.cpp

JeffGarland avatar Nov 29 '21 12:11 JeffGarland

Yes, I know the others options to do this job. But, as boost::posix_time::to_iso_extended_wstring exits and is publicity accesible; I would like to use it. But to_iso_extended_wstring has this locale problem, when no classic locale is set.

jalegido avatar Nov 29 '21 13:11 jalegido

From the initial problem report it seemed like it wasn't just wstring with the problem. And for sure the code here has no dependency on locales -- in particular the global one -- which is a property I'd like to keep. If we wanted a locale based solution it should be an overload.

JeffGarland avatar Nov 29 '21 14:11 JeffGarland

I think these public functions should not dependencies on locales. But as ISO is always in classic locale, I think it should be good to set imbue(std::locale::classic()) in the function to_simple_string_type to solve future problems with parse ISO string in other applications or languages.

jalegido avatar Nov 29 '21 14:11 jalegido

The classic locale doesn't have anything to do with ISO time representations -- as far as I know, you'll never get ISO out of time_put/get without forcing the format. The only thing that could be used there are the punctuation chars, which is the original issue you're having. So maybe if there was a tweak we could make it would be that the separators be a defaulted parameter to the function.

https://en.cppreference.com/w/cpp/locale/numpunct

JeffGarland avatar Nov 29 '21 15:11 JeffGarland

Ok, that should be enough.

jalegido avatar Nov 29 '21 15:11 jalegido

I would like that next code will generate correct output:

#include <iostream>
#include <boost/date_time.hpp>

int main()
{
    std::locale::global(std::locale("es_ES"));
    boost::posix_time::ptime dt(boost::gregorian::date(2021, 11, 29), boost::posix_time::time_duration(10, 11, 12, 123456));
    std::wcout << boost::posix_time::to_iso_extended_wstring(dt) << std::endl;

    std::locale::global(std::locale("ar_EG"));
    std::wcout << boost::posix_time::to_iso_extended_wstring(dt) << std::endl;
}

Current output MSVC 16.11.7 2021-11-29T10:11:12.123.456 2021-11-29T10:11:12.123,456

Expected output: 2021-11-29T10:11:12.123456 2021-11-29T10:11:12.123456

jalegido avatar Nov 29 '21 16:11 jalegido