Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#13280 closed Bugs (worksforme)

"20170101" gives surprising result parsed as extended ISO 8601

Reported by: Thomas Guest <thomas.guest@…> Owned by: James E. King, III
Milestone: To Be Determined Component: date_time
Version: Boost 1.65.0 Severity: Problem
Keywords: Cc:

Description

#include <locale>
#include <iostream>
#include <sstream>
#include <boost/date_time/gregorian/gregorian.hpp>

int main()
{
	std::string value = "20170105";

	boost::gregorian::date d;

	auto * f = new boost::gregorian::date_input_facet();
	f->set_iso_extended_format();

	std::stringstream ss;
	std::locale loc(std::locale::classic(), f);
	ss.imbue(loc);
	ss << value;
	ss >> d;

	std::cout << value << " => " << d << '\n';
	return 0;
}

When I run this I get:

20170105 => 2017-Oct-01

I expected an exception to be raised.

Change History (5)

comment:1 by Thomas Guest <thomas.guest@…>, 5 years ago

Apologies - version should be 1.65.1

comment:2 by James E. King, III, 5 years ago

Version: Boost 1.63.0Boost 1.65.0

comment:3 by James E. King, III, 5 years ago

Owner: changed from az_sw_dude to James E. King, III

comment:4 by James E. King, III, 5 years ago

Resolution: worksforme
Status: newclosed

I just added this test to testdate_input_facet and using Boost 1.66.0 with msvc-14.1 it works properly. You did not enable exceptions in your example. Before calling imbue, you want to call:

    ss.exceptions(std::ios_base::failbit); // turn on exceptions

if you want an exception to be raised.

Example (add this to the testdate_input_facet unit test to see it work):

  // prove trac 13280 on extended iso format is behaving properly
  {
    std::string value = "20171221";
    date_input_facet *f13280_bad = new date_input_facet();
    f13280_bad->set_iso_extended_format();
    std::stringstream s13280_bad;
    s13280_bad.imbue(std::locale(s13280_bad.getloc(), f13280_bad));
    s13280_bad << value;
    boost::gregorian::date d13280_bad;
    check("extended ISO with YYYYMMDD sets failbit", 
          failure_test(d13280_bad, value, f13280_bad));
    check("extended iso with YYYYMMDD is not a date", 
          d13280_bad.is_not_a_date());
  }

comment:5 by James E. King, III, 5 years ago

The documentation is clear on this one as well:

http://www.boost.org/doc/libs/1_66_0/doc/html/date_time/date_time_io.html

Exception Handling on Streams

When an error occurs during the input streaming process, the std::ios_base::failbit 
will (always) be set on the stream. It is also possible to have exceptions thrown 
when an error occurs. To "turn on" these exceptions, call the stream's exceptions
function with a parameter of std::ios_base::failbit.
Note: See TracTickets for help on using tickets.