2011-01-26 72 views
1

我想使用Boost的日期時間庫以自定義格式解析日期/時間字符串。我試圖使用的格式非常不尋常,因爲它包含Posix時區描述字符串。 docs爲庫clearly state有一個標誌(%ZP)可用於處理Posix時區字符串的輸入和輸出。我試圖解析的值來自Web瀏覽器,而不是編寫JS來執行區域字符串中指定的轉換,然後以UTC發送到服務器,我寧願只做它服務器端(因爲Boost應該很容易做到這一點)。很明顯,如果它工作,我不會在這裏發佈。此代碼會拋出一個boost::bad_lexical_cast,其值爲「源類型值不能被解釋爲目標」。使用帶時區字符串的Boost日期時間庫解析失敗

using namespace boost::posix_time; 
using namespace boost::local_time; 
using namespace boost::gregorian; 

std::istringstream ss("1989-11-09T15:30:42.005;PST-8PDT,M3.2.0,M11.1.0"); 
ss.exceptions(std::ios_base::failbit); 
local_time_input_facet* facet = new local_time_input_facet("%Y-%m-%dT%H:%M:%S%F;%ZP"); 
ss.imbue(std::locale(ss.getloc(), facet)); 

local_date_time ldt(not_a_date_time); 

ss >> ldt; // do the parse 

std::cout << ldt.to_string(); 

然而,如果你用"%Y-%m-%dT%H:%M:%S%F;"替換格式字符串,解析成功就好了(當然它輸出在錯誤的時區的值)。

任何想法我做錯了什麼? %ZP標誌的文檔沒有示例,所以我不確定它應該如何使用。

+0

你是否得到這個工作? – Nim 2011-01-27 09:10:22

回答

1

我認爲你的格式字符串應該是這樣的:%Y-%m-%dT%H:%M:%s *;%ZP%s *將匹配秒和小數秒。隨着這一變化,上面的代碼運行,bizarely雖然,輸出我得到的是:

1989-Nov-09 15:30:42.005000 ST

不知道爲什麼它說ST而非,但時區信息不會被正確解析,如果你改變了日期例如到11月01日,那麼它將報告PDT

編輯:時區對象的描述是here


好,由與此左右搞亂,看來解析誤差由;的存在造成的,從原來的字符串中移除,使得其變爲:

std::istringstream ss("1989-10-16T15:30:42.005 PST-8PDT,M3.2.0,M10.2.0"); 

和更改格式字符串:

local_time_input_facet* facet = new local_time_input_facet("%Y-%m-%d %H:%M:%s %ZP"); 

正確地報告:

1989-Oct-16 15:30:42.005000 PST 

如果再次改變輸入字符串:

std::istringstream ss("1989-10-16T15:30:42.005 PST-8PDT,M3.2.0,M11.1.0"); 

輸出再次正確:

1989-Oct-16 15:30:42.005000 PDT 

這告訴我,是確實履行嵌入在字符串中的時區信息.. 。所以有趣的問題是,爲什麼它會出現;

進一步更新,看起來輸入字符串只能包含字母數字,集合.:-,和空格中的字符 - 小數位後 - 即您不能將時區信息與除上面列出的任何字符(這並不是詳盡無遺,沒有時間去測試它們全部!)

+0

當我看到你的答案時,我非常興奮,但我已經嘗試過了,它不適合我。我也嘗試使用`%s`而不是`%s *`得到相同的結果。我相信你錯誤地解釋了關於`%s *`的文檔;星號表示一個腳註,表示它是Boost唯一的行爲(因爲這些格式說明符大部分與`strftime()`相同)。你使用的是什麼版本的Boost?我正在使用1.40.0。 – rmeador 2011-01-26 16:29:23

相關問題