名稱空間
變體
操作

std::time_get<CharT,InputIt>::get, std::time_get<CharT,InputIt>::do_get

來自 cppreference.com
< cpp‎ | locale‎ | time get
 
 
 
 
 
定義於標頭檔案 <locale>
public:

iter_type get( iter_type beg, iter_type end, std::ios_base& str,
               std::ios_base::iostate& err, std::tm* t,

               const char_type* fmtbeg, const char_type* fmtend ) const;
(1) (C++11 起)
protected:

virtual iter_type do_get( iter_type beg, iter_type end, std::ios_base& str,
                          std::ios_base::iostate& err, std::tm *t,

                          char format, char modifier ) const;
(2) (C++11 起)
1) 根據字元序列 [fmtbeg, fmtend) 中提供的格式,從輸入字元序列 [beg, end) 解析日期和時間。格式應遵循下文所述的格式,儘管每個格式說明符的實際處理可以透過重寫 do_get 進行自定義。get 函式執行以下操作:首先,透過執行 err = std::ios_base::goodbit 清除 err 中的錯誤位。然後進入一個迴圈,當以下任何條件為真時(按此順序檢查)終止:
a) 已從格式字串中讀取所有字元 (fmtbeg == fmtend)。
b) 存在解析錯誤 (err != std::ios_base::goodbit)。
c) 已從輸入序列中讀取所有字元 (beg == end)。如果此條件終止迴圈,則函式在 err 中設定 eofbitfailbit
在迴圈體中,執行以下步驟:
a) 如果格式字串中的下一個字元是 '%',後跟一個或兩個字元形成有效的 std::get_time 轉換說明符(見下文),則這些字元用於呼叫 do_get(beg, end, str, err, t, format, modifier),其中 format 是主要的轉換說明符字元,而 modifier 是可選的修飾符(如果存在,它出現在 % 和格式字元之間)。如果沒有修飾符,則使用值 '\0'。如果格式字串含糊不清或結束得太早,無法在 '%' 之後確定轉換說明符,則在 err 中設定 eofbit 並終止迴圈。如果在呼叫 do_get 之後,err 中未設定任何錯誤位,則函式遞增 fmtbeg 以指向轉換說明符之後並繼續迴圈。
b) 如果下一個字元是空格(由流 str 中提供的區域設定指示,即 std::isspace(*fmtbeg, str.getloc()) == true),則函式不斷遞增 fmtbeg,直到它等於 fmtend 或指向非空格字元。
c) 如果格式字串中的下一個字元與輸入流中的下一個字元根據不區分大小寫的比較等效,則函式將兩個序列都前進一個字元 ++fmtbeg, ++beg; 並繼續迴圈。否則,它在 err 中設定 failbit
2) 從輸入序列 [beg, end) 解析一個轉換說明符,並相應地更新由 t 指向的 std::tm 結構。
首先,透過執行 err = std::ios_base::goodbit 清除 err 中的錯誤位。然後從輸入序列 [beg, end) 中讀取 std::time_get 格式說明符預期的字元,該格式說明符由 '%'modifier(如果不是 '\0')和 format 組合而成。如果字元未組合成有效的轉換說明符,則在 err 中設定 failbit。如果在讀取字元後到達輸入流的末尾,則在 err 中設定 eofbit。如果輸入字串解析成功,則更新 *t 的相應欄位。
對於複雜的轉換說明符,例如 '%x''%c',或使用修飾符 'E''O' 的指令,函式可能無法確定要儲存在 *t 中的某些值。在這種情況下,它在 err 中設定 eofbit,並使這些欄位處於未指定狀態。

目錄

[edit] 引數

beg - 指定要解析序列起始的迭代器
end - 要解析序列的結束迭代器之後一個位置
str - 此函式在需要時用於獲取區域設定 facet 的流物件,例如 std::ctype 用於跳過空格或 std::collate 用於比較字串
err - 由該函式修改以指示錯誤的流錯誤標誌物件
t - 指向將儲存此函式呼叫結果的 std::tm 物件的指標
fmtbeg - 指向指定轉換格式(見下文)的 char_type 字元序列的第一個字元的指標
fmtend - 指向指定轉換格式的 char_type 字元序列的最後一個字元之後一個位置的指標
format - 命名轉換說明符的字元
modifier - 可選的修飾符,可能出現在 % 和轉換說明符之間


格式字串由零個或多個轉換說明符、空白字元和普通字元(除了 %)組成。每個普通字元應在不區分大小寫的比較中與輸入流中的一個字元匹配。每個空白字元匹配輸入字串中的任意空白。每個轉換規範以 % 字元開頭,可選地後跟 EO 修飾符(如果區域設定不支援則忽略),然後是確定說明符行為的字元。格式說明符與 POSIX 函式 strptime() 匹配。

轉換
說明符
解釋 寫入欄位
% 匹配字面量 %。完整的轉換規範必須是 %% (無)
t 匹配任意空白 (無)
n 匹配任意空白 (無)
Y 解析四位十進位制數字的完整年份,允許但不要求前導零 tm_year
EY 解析替代表示形式的年份,例如平成23年(Heisei 23年),在ja_JP區域設定中寫入2011到tm_year tm_year
y 解析年份的最後兩位數字作為十進位制數。範圍 [69,99] 導致值 1969 到 1999,範圍 [00,68] 導致 2000-2068 tm_year
Oy 使用替代數字系統解析年份的最後兩位數字,例如在ja_JP區域設定中,十一被解析為11 tm_year
Ey 年份解析為區域設定的替代日曆週期 %EC 的偏移量 tm_year
C 年份的前兩位數字解析為十進位制數(範圍 [00,99] tm_year
EC 解析區域設定中替代表示形式的基本年份(週期)的名稱,例如 ja_JP 中的平成(Heisei 時代) tm_year
b 解析月份名稱,可以是全稱或縮寫,例如 Oct tm_mon
h b 的同義詞 tm_mon
B b 的同義詞 tm_mon
m 月份解析為十進位制數(範圍 [01,12]),允許但不要求前導零 tm_mon
Om 使用替代數字系統解析月份,例如在ja_JP區域設定中,十二被解析為12 tm_mon
U 一年中的週數解析為十進位制數(星期日是第一天)(範圍 [00,53]),允許但不要求前導零 tm_year, tm_wday, tm_yday
OU 使用替代數字系統解析一年中的週數,與 %U 相同,例如在ja_JP區域設定中,五十二被解析為52 tm_year, tm_wday, tm_yday
W 一年中的週數解析為十進位制數(星期一是第一天)(範圍 [00,53]),允許但不要求前導零 tm_year, tm_wday, tm_yday
OW 使用替代數字系統解析一年中的週數,與 %W 相同,例如在ja_JP區域設定中,五十二被解析為52 tm_year, tm_wday, tm_yday
年/月中的日
j 一年中的日期解析為十進位制數(範圍 [001,366]),允許但不要求前導零 tm_yday
d 月份中的日期解析為十進位制數(範圍 [01,31]),允許但不要求前導零 tm_mday
Od 使用替代數字系統解析月份中的日期,例如在ja_JP區域設定中,二十七被解析為27,允許但不要求前導零 tm_mday
e d 的同義詞 tm_mday
Oe Od 的同義詞 tm_mday
星期幾
a 解析星期幾的名稱,可以是全稱或縮寫,例如 Fri tm_wday
A a 的同義詞 tm_wday
w 工作日解析為十進位制數,其中星期日是 0(範圍 [0-6] tm_wday
Ow 使用替代數字系統解析工作日為十進位制數,其中星期日是 0,例如在ja_JP區域設定中,二被解析為2 tm_wday
時、分、秒
H 小時解析為十進位制數,24小時制(範圍 [00-23]),允許但不要求前導零 tm_hour
OH 使用替代數字系統從24小時制解析小時,例如在ja_JP區域設定中,十八被解析為18 tm_hour
I 小時解析為十進位制數,12小時制(範圍 [01,12]),允許但不要求前導零 tm_hour
OI 使用替代數字系統從12小時制解析小時,例如在ja_JP區域設定中,六被讀取為06 tm_hour
M 分鐘解析為十進位制數(範圍 [00,59]),允許但不要求前導零 tm_min
OM 使用替代數字系統解析分鐘,例如在ja_JP區域設定中,二十五被解析為25 tm_min
S 秒數解析為十進位制數(範圍 [00,60]),允許但不要求前導零 tm_sec
OS 使用替代數字系統解析秒數,例如在ja_JP區域設定中,二十四被解析為24 tm_sec
其他
c 解析區域設定的標準日期和時間字串格式,例如 Sun Oct 17 04:41:13 2010(取決於區域設定) 所有
Ec 解析區域設定的替代日期和時間字串格式,例如在ja_JP區域設定中,期望平成23年(Heisei 23年)而不是2011年(2011年) 所有
x 解析區域設定的標準日期表示 所有
Ex 解析區域設定的替代日期表示,例如在ja_JP區域設定中,期望平成23年(Heisei 23年)而不是2011年(2011年) 所有
X 解析區域設定的標準時間表示 所有
EX 解析區域設定的替代時間表示 所有
D 等價於 "%m / %d / %y " tm_mon, tm_mday, tm_year
r 解析區域設定的標準12小時制時間(在 POSIX 中,"%I : %M : %S %p" tm_hour, tm_min, tm_sec
R 等價於 "%H : %M" tm_hour, tm_min
T 等價於 "%H : %M : %S" tm_hour, tm_min, tm_sec
p 解析區域設定中相當於上午或下午的表示 tm_hour

注意:tm_isdst 不會被寫入,需要在使用諸如 mktime 等函式之前明確設定。

[edit] 返回值

指向 [beg, end) 中成功解析的最後一個字元之後一個位置的迭代器。

[edit] 注意

對於格式字串中非空白非 '%' 字元的不區分大小寫比較,通常(但不一定)使用 str 提供的區域設定的 std::collate facet。

如果遇到解析錯誤,此函式的許多實現會使 *t 完全不受影響。

這些函式是否將其未直接設定的 *t 中的欄位歸零是未指定的:可移植程式在呼叫 get() 之前應將每個欄位初始化為零。

[edit] 示例

#include <iomanip>
#include <iostream>
#include <locale>
#include <sstream>
 
int main()
{
    std::istringstream ss("2026-März-12 23:45:56");
    ss.imbue(std::locale("de_DE.utf8"));
 
    auto& f = std::use_facet<std::time_get<char>>(ss.getloc());
    std::tm t{};
    std::string s = "%Y-%b-%d %H:%M:%S";
    std::ios_base::iostate err = std::ios_base::goodbit;
    auto ret = f.get({ss}, {}, ss, err, &t, &s[0], &s[0] + s.size());
    ss.setstate(err);
    std::istreambuf_iterator<char> last{};
 
    if (ss)
    {
        std::cout << "Successfully parsed as " << std::put_time(&t, "%c") << '\n';
        if (ret != last)
        {
            std::cout << "Remaining content: ";
            std::copy(ret, last, std::ostreambuf_iterator<char>(std::cout));
        }
        else
            std::cout << "The input was fully consumed.";
    }
    else
    {
        std::cout << "Parse failed.\nUnparsed string: ";
        std::copy(ret, last, std::ostreambuf_iterator<char>(std::cout));
    }
    std::cout << '\n';
}

輸出

Successfully parsed as Sun Mar 12 23:45:56 2026
The input was fully consumed.

[edit] 另見

(C++11)
解析指定格式的日期/時間值
(函式模板) [編輯]