Esto parece ser un problema con el uso de %e
en su faceta de entrada.
El Boost.Gregorian documentation especifica que:
% d día del mes como decimal 01 a 31
% e # Como% d, el día del mes como un número decimal, pero un cero inicial se reemplaza por un espacio
El problema es que si nos fijamos en la parte superior de la documentación, se dará cuenta esta advertencia:
Las banderas marcados con un signo de almohadilla (#) son implementados por configuración regional del sistema y se sabe que falta en algunas plataformas
que he probado los siguientes casos:
input_string = " 1"
date_format = "%e"
result = failed
input_string = "01"
date_format = "%e"
result = success
input_string = "2000 Mar 1"
date_format = "%Y %b %e"
result = failed
input_string = "2000 Mar 1"
date_format = "%Y %b %e"
result = success
input_string = "2000 Mar 01"
date_format = "%Y %b %e"
result = success
parece por lo tanto que se trata de una limitación de la aplicación Boost (o, al menos, el hecho de que se basa en una configuración regional específica para el análisis de %e
): el análisis falla cuando %e
es el primer elemento en la cadena de entrada, y se utiliza un espacio en lugar de un 0
principal.
Mi (ciega) suposición sería que el problema proviene de la tendencia de stringstream a saltear espacios en blanco. Intenté encontrar una solución con el std::noskipws
, sin embargo, no pude encontrar algo que funcionara.
Como solución alternativa, recomendaría agregar un cero a la izquierda o, si es posible, usar un formato de fecha diferente.
Otra solución alternativa sería agregar manualmente el espacio e invertir el orden de las "palabras" en la cadena. He logrado una solución de trabajo de la siguiente manera:
#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <string>
int main(void) {
using namespace boost::gregorian;
std::string input_date("1 Mar 2000");
{ // local scope to remove temporary variables as soon as possible
std::stringstream tmp_ss(input_date);
std::string tmp;
input_date.clear(); // empty the initial string
while (tmp_ss >> tmp) {
input_date.insert(0, tmp); // insert word at beginning of string
if(tmp.size() == 1) // if word is one char long, add extra space
input_date.insert(0, " ");
input_date.insert(0, " "); // add space to separate words
}
}
std::stringstream ss(input_date);
// The order of the date is reversed.
date_input_facet *df = new date_input_facet("%Y %b %e");
ss.imbue(std::locale(ss.getloc(), df));
date d; //conversion works
ss >> d;
std::cout << "'" << d << "'" << std::endl; // ouputs date correctly.
return 0;
}
Buena suerte,