8

私は次のように astd::stringを aに変換しようとしていboost::gregorian::dateます:

using namespace boost::gregorian;

std::string str = "1 Mar 2012";
std::stringstream ss(str);
date_input_facet *df = new date_input_facet("%e %b %Y");
ss.imbue(std::locale(ss.getloc(), df));
date d;

ss >> d;  //conversion fails to not-a-date-time

std::cout << "'" << d << "'" << std::endl;  //'not-a-date-time'

ただし、文字列に「01 Mar 2012」が含まれている場合、変換は成功します。

「1 Mar 2012」のような文字列を同等のものに変換するにはどうすればよいboost::gregorian::dateですか?

4

1 に答える 1

10

%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;
}    

幸運を、

于 2012-03-01T14:44:25.860 に答える