2017-10-19 129 views
1

假設我從Web服務器接收到要解析的字符串。該字符串包含格式爲YYYY-MM-DD的日期。 我想要的是將其轉換爲表示當天開始的時間戳,因此我不需要秒,分鐘和小時。解析日期字符串以從時間戳中刪除小時,分鐘和秒

作爲一個虛擬示例,我試圖提取當前日期的時間戳,一旦轉換爲YYYY-MM-DD格式。下面的代碼:

#include <chrono>                                                                
#include <iomanip>                                                                
#include <iostream>                                                                
#include <sstream> 
int main() 
{ 
    // Current time at GMT 
    std::time_t now = std::time(0); 
    std::tm *now_tm = std::gmtime(&now); 
    std::ostringstream oss; 
    // Extract yyyy-mm-dd = %F 
    oss << std::put_time(now_tm, "%F"); 
    // Use oss to get a date without seconds from 
    // current time at gmt 
    std::tm tm; 
    std::istringstream ss(oss.str()); 
    ss >> std::get_time(&tm, "%F"); 
    std::time_t current_date = std::mktime(&tm); 
    std::cout << oss.str() << std::endl; 
    std::cout << "cd: " << current_date << std::endl; 
    return 0; 
} 

輸出是:

2017-10-19 
cd: 1908337984324104 

提取的時間戳顯然是錯誤的。使用%F格式解析2017-10-19字符串時問題出在哪裏?

回答

1

documentation of std::get_time列出沒有轉換說明符%F。當檢查流標誌(你總是應該這樣做!)時,它也會告訴轉換失敗,至少在我的編譯器中是這樣。

因此,通過用%Y-%m-%d代替它,轉換成功。最後,你默認構造了tm變量而不用調零(例如通過值初始化)。當解決這個爲好,該代碼按預期工作:

#include <chrono>                                                                
#include <iomanip>                                                                
#include <iostream>                                                                
#include <sstream> 
int main() 
{ 
    // Current time at GMT 
    std::time_t now = std::time(0); 
    std::tm *now_tm = std::gmtime(&now); 
    std::ostringstream oss; 
    // Extract yyyy-mm-dd = %F 
    oss << std::put_time(now_tm, "%Y-%m-%d"); 
    // Use oss to get a date without seconds from 
    // current time at gmt 
    std::tm tm{ }; // value-initialize! 
    std::istringstream ss(oss.str()); 
    ss >> std::get_time(&tm, "%Y-%m-%d"); 
    if(!ss) std::cout << "conversion error\n"; 
    else { 
     std::time_t current_date = std::mktime(&tm); 
     std::cout << current_date << '\n'; 
     std::cout << "cd: " << current_date << '\n'; 
    } 
    return 0; 
} 

http://coliru.stacked-crooked.com/a/d86aa1e1d890a14d

+0

非常感謝!我正在查看另一個時間格式化函數的文檔,猜測它會是一樣的。我錯了。 – nessuno

1

你可以做到這一點,而不使用Howard Hinnant's, free, open-source, header-only chrono-extension library離開chrono型系統的安全性。

#include "date/date.h" 
#include <iostream> 

int 
main() 
{ 
    std::istringstream ss{"2017-10-19"}; 
    date::sys_seconds tp; 
    ss >> date::parse("%F", tp); 
    std::cout << date::format("%F\n", tp); 
    using date::operator<<; 
    std::cout << "cd: " << tp.time_since_epoch() << '\n'; 
} 

date::sys_secondsstd::chrono::time_point計數在Unix Timechrono::seconds。您可以使用%F直接解析它。您也可以使用相同的格式字符串(%F)對其進行格式化,並檢查底層計數chrono::seconds。本程序輸出:

2017-10-19 
cd: 1508371200s 
+0

太好了。感謝您的建議。保持我的贊成 – nessuno