Questo sembra essere un problema con l'uso di %e
nel proprio aspetto.
Il Boost.Gregorian documentation specifica che:
% d Giorno del mese come decimale 01-31
% e # Come% d, il giorno del mese come numero decimale, ma uno zero iniziale è sostituito da uno spazio
Il problema è che se si guarda la parte superiore della documentazione, si noterà questo avvertimento:
Le bandiere contrassegnati con un simbolo cancelletto (#) sono attuati da impostazioni internazionali del sistema e sono noti per essere mancante su alcune piattaforme
ho provato i seguenti casi:
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
sembra quindi che questa è una limitazione dell'implementazione Boost (o almeno, il fatto che si basa su una locale specifica per l'analisi di %e
): l'analisi non riesce quando %e
è il primo elemento nella stringa di input e viene utilizzato uno spazio anziché uno 0
iniziale.
La mia ipotesi (cieca) sarebbe che il problema derivi dalla tendenza dello stringstream a saltare gli spazi bianchi. Ho cercato di trovare una soluzione con lo std::noskipws
, tuttavia, non è stato possibile trovare qualcosa che funzionasse.
Per ovviare al problema, è consigliabile aggiungere uno zero iniziale o, se possibile, utilizzare un formato di data diverso.
Un'altra soluzione sarebbe quella di aggiungere manualmente lo spazio e invertire l'ordine delle "parole" nella stringa. Ho realizzato una soluzione di lavoro come questo:
#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;
}
Buona fortuna,