Boost logo

Boost :

From: Andrew Gvozdev (andrew.gvozdev_at_[hidden])
Date: 2007-03-01 16:56:06


There is a problem in date_time library with function to_iso_string(date)
when a global locale is set. The library creates a stream to output year
which applies global locale formatting including thousand separators, i.e.
"2,002". Look at this test:

Added to testtime_formatters.cpp:

 const std::locale&
original_locale(std::locale::global(std::locale("en_US.utf8")));

 check("simple+loc: [" + t1_result + "]==[" + to_simple_string(t1) + "]",
       t1_result == to_simple_string(t1));
 check("iso+loc: [" + iso_result + "]==[" + to_iso_string(t1) + "]",
       iso_result == to_iso_string(t1));
 check("iso ext+loc: [" + iso_ext_result + "]==[" +
to_iso_extended_string(t1) + "]",
       iso_ext_result == to_iso_extended_string(t1));
 std::locale::global(original_locale);

results in:

execute-test
../../../bin/boost/libs/date_time/test/testtime_formatters.test/gcc/debug/te
sttime_formatters.run
====== BEGIN OUTPUT ======
2002-Jan-01 01:02:03
...
FAIL :: simple+loc: [2002-Jan-01 01:02:03]==[2,002-Jan-01 01:02:03]
FAIL :: iso+loc: [20020101T010203]==[2,0020101T010203]
FAIL :: iso ext+loc: [2002-01-01T01:02:03]==[2,002-01-01T01:02:03]
...
14 Tests Executed: 3 FAILURES

As email at the end suggests this problem is known for some time. Are there
any plans to fix it? If I may suggest, the fix could be to imbue the stream
with classic locale for the purpose of year output:

date_formatting.hpp

 template<class ymd_type, class format_type, class charT=char> class
ymd_formatter {
 public:
   static std::basic_string<charT> ymd_to_string(ymd_type ymd)
   {
     typedef typename ymd_type::month_type month_type;
     std::basic_ostringstream<charT> ss;
     ss.imbue(std::locale::classic()); // <--- The fix
     ss << ymd.year;
     ss.imbue(std::locale::locale()); // <--- The fix
     if (format_type::has_date_sep_chars()) {
       ss << format_type::month_sep_char();
     }
     //this name is a bit ugly, oh well....
 
month_formatter<month_type,format_type,charT>::format_month(ymd.month,ss);
     if (format_type::has_date_sep_chars()) {
       ss << format_type::day_sep_char();
     }
     ss << std::setw(2) << std::setfill(ss.widen('0'))
         << ymd.day;
     return ss.str();
   }
 };

Thanks,
Andrew

> From: Jeff Garland <jeff <at> crystalclearsoftware.com>
> Subject: Re: date serialization fails with non-standard locales
> Newsgroups: gmane.comp.lib.boost.user
> Date: 2005-05-28 14:39:38 GMT (1 year, 39 weeks, 4 days and
> 15 minutes ago)
>
> On Sat, 28 May 2005 02:10:02 +0200, Paolo Coletta wrote
> > I'm not sure if this is a bug or if I'm misusing the
> library. It seems
> > that serializing boost::posix_time_ptime fails when using
> non-standard
> > locale (Windows Xp OS - vc 7.1 compiler - boost updated
> from CVS few
> > days ago).
> >
> > As an example, try adding
> >
> > std::locale::global( std::locale( "en" ) );
> >
> > as the first line of the testtime_serialize.cpp; this
> causes the test
> > to fail when doing
> >
> > ia >> pt2;
> >
> > I tried to understand what was happening, and it seems to
> me that the
> > problem is in keeping into account locale when serializing, while
> > ignoring it while unserializing.
> > In greg_serialize.hpp
> > to_iso_string(d)
> > may generate something like "2,0050527"; the method
> > from_undelimited_string(ds)
> > used to load the serialized date, expects a 4,2,2 format.
>
> It looks like the problem is that the stream output is
> including a thousands seperator when it shouldn't. The
> serialization should be 20050527 with no number seperators.
> So it appears that we cannot depend on the stream not using
> the thousands separtor in date_time/date_formatting.hpp (line
> 81) where the year is actully output:
>
> std::basic_ostringstream<charT> ss;
> ss << ymd.year;
>
> We'll look into fixing this...
>
> Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk