%e
これは、入力ファセットでの使用に問題があるようです。
Boost.Gregorianのドキュメントでは、次のように指定されています。
%d 10 進数 01 から 31 としての月の日
%e # %d と同様に、日付は 10 進数ですが、先頭のゼロはスペースに置き換えられます
問題は、ドキュメントの上部を見ると、次の警告に気付くことです。
ハッシュ記号 (#) でマークされたフラグはシステム ロケールによって実装され、一部のプラットフォームでは欠落していることが知られています。
私は次のケースを試しました:
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
したがって、これは Boost 実装の制限 (または少なくとも、 の解析のために特定のロケールに依存しているという事実) のようです:が入力文字列の最初の項目で、スペースが使用されている%e
場合、解析は失敗します。%e
先頭の の代わりに0
.
私の(盲目的な)推測では、問題は stringstream が空白をスキップする傾向にあることにあると思います。で解決策を見つけようとしましたが、std::noskipws
機能するものが見つかりませんでした。
回避策として、先行ゼロを追加するか、可能であれば別の日付形式を使用することをお勧めします。
別の回避策は、スペースを手動で追加し、文字列内の「単語」の順序を逆にすることです。私は次のような実用的なソリューションを達成しました:
#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;
}
幸運を、