命名空间
变体
操作

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

来自 cppreference.cn
< 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) (since 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) (since 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) 中解析一个转换说明符,并相应地更新 std::tm 结构(由 t 指向)。
首先,通过执行 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,并将这些字段保留为未指定状态。

目录

[编辑] 参数

beg - 指示要解析的序列的开头的迭代器
end - 要解析的序列的末尾迭代器之后的一个位置
str - 此函数用于在需要时获取区域设置侧面的流对象,例如 std::ctype 以跳过空格或 std::collate 以比较字符串
err - 流错误标志对象,此函数会修改该对象以指示错误
t - 指向 std::tm 对象的指针,该对象将保存此函数调用的结果
fmtbeg - 指向指定转换格式的 char_type 字符序列的第一个字符的指针(见下文)
fmtend - 指向指定转换格式的 char_type 字符序列的最后一个字符之后的一个位置的指针
format - 命名转换说明符的字符
modifier - 可能出现在 % 和转换说明符之间的可选修饰符


格式字符串由零个或多个转换说明符、空格字符和普通字符(除了 %)组成。 每个普通字符都应与输入流中的一个字符匹配(不区分大小写比较)。 每个空格字符都与输入字符串中的任意空格匹配。 每个转换规范都以 % 字符开头,可选地后跟 EO 修饰符(如果区域设置不支持则忽略),后跟确定说明符行为的字符。 格式说明符与 POSIX 函数 strptime() 匹配

转换
说明符
说明 写入字段
% % 匹配字面量 %。 完整的转换规范必须是 %%
t (无) 匹配字面量 %。 完整的转换规范必须是 %%
n (无) 匹配字面量 %。 完整的转换规范必须是 %%
空格
Y 匹配任何空格
EY 年份解析为 4 位十进制数字,允许但不要求前导零
y tm_year
Oy 以替代表示形式解析年份,例如 平成23年(平成 23 年),在 ja_JP 区域设置中将 2011 写入 tm_year
Ey 年份的后 2 位解析为十进制数字。 范围 [69,99] 导致值 1969 到 1999,范围 [00,68] 导致 2000-2068
C 使用替代数字系统解析年份的后 2 位,例如 在 ja_JP 区域设置中,十一 被解析为 11
EC 年份解析为与区域设置的替代日历期间 %EC 的偏移量
b 年份的前 2 位解析为十进制数字(范围 [00,99] tm_mon
h 解析区域设置的替代表示形式中的基准年份(期间)的名称,例如 ja_JP 中的 平成(平成时代) tm_mon
B 解析区域设置的替代表示形式中的基准年份(期间)的名称,例如 ja_JP 中的 平成(平成时代) tm_mon
m 解析月份名称,可以是完整名称或缩写名称,例如 Oct tm_mon
Om b 的同义词 tm_mon
U 月份解析为十进制数字(范围 [01,12]),允许但不要求前导零 tm_year, tm_wday, tm_yday
OU 使用替代数字系统解析月份,例如 在 ja_JP 区域设置中,十二 解析为 12 tm_year, tm_wday, tm_yday
W 年份的周数解析为十进制数字(星期日是一周的第一天)(范围 [00,53]),允许但不要求前导零 tm_year, tm_wday, tm_yday
OW 使用替代数字系统解析年份的周数,与 %U 相同,例如 在 ja_JP 区域设置中,五十二 解析为 52 tm_year, tm_wday, tm_yday
年/月日
j 年份的周数解析为十进制数字(星期一是一周的第一天)(范围 [00,53]),允许但不要求前导零 tm_yday
d 使用替代数字系统解析年份的周数,与 %W 相同,例如 在 ja_JP 区域设置中,五十二 解析为 52 tm_mday
Od 年份中的天数解析为十进制数字(范围 [001,366]),允许但不要求前导零 tm_mday
e 月份中的天数解析为十进制数字(范围 [01,31]),允许但不要求前导零 tm_mday
Oe d 的同义词 tm_mday
星期几
a 使用替代数字系统解析月份中的天数,例如 在 ja_JP 区域设置中,二十七 解析为 27,允许但不要求前导零 tm_wday
A Od 的同义词 tm_wday
w 解析星期几的名称,可以是完整名称或缩写名称,例如 Fri tm_wday
Ow a 的同义词 tm_wday
小时、分钟、秒
H 工作日解析为十进制数字,其中星期日为 0(范围 [0-6] tm_hour
OH 工作日解析为十进制数字,其中星期日为 0,使用替代数字系统,例如 在 ja_JP 区域设置中,二 解析为 2 tm_hour
I 小时解析为十进制数字,24 小时制(范围 [00-23]),允许但不要求前导零 tm_hour
OI 使用替代数字系统从 24 小时制解析小时,例如 在 ja_JP 区域设置中,十八 解析为 18 tm_hour
M 小时解析为十进制数字,12 小时制(范围 [01,12]),允许但不要求前导零 tm_min
OM 使用替代数字系统从 12 小时制解析小时,例如 在 ja_JP 区域设置中,六 读取为 06 tm_min
S 分钟解析为十进制数字(范围 [00,59]),允许但不要求前导零 tm_sec
OS 使用替代数字系统解析分钟,例如 在 ja_JP 区域设置中,二十五 解析为 25 tm_sec
其他
c 解析为十进制数字(范围 [00,60]),允许但不要求前导零 全部
Ec 使用替代数字系统解析,例如 在 ja_JP 区域设置中,二十四 解析为 24 全部
x 解析区域设置的标准日期和时间字符串格式,例如 Sun Oct 17 04:41:13 2010(区域设置相关) 全部
Ex 解析区域设置的替代日期和时间字符串格式,例如 在 ja_JP 区域设置中,期望 平成23年(平成 23 年)而不是 2011年(2011 年) 全部
X 解析区域设置的标准日期表示形式 全部
EX 解析区域设置的替代日期表示形式,例如 在 ja_JP 区域设置中,期望 平成23年(平成 23 年)而不是 2011年(2011 年) 全部
D 解析区域设置的标准时间表示形式 tm_mon, tm_mday, tm_year
r 解析区域设置的替代时间表示形式 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 等函数

[编辑] 返回值

迭代器,指向 [beg, end) 中成功解析的最后一个字符之后的位置。

[编辑] 注意

对于格式字符串中非空格非 '%' 字符的不区分大小写比较,通常(但不一定)使用 str 提供的区域设置的 std::collate 侧面。

如果遇到解析错误,此函数的许多实现会将 *t 完全保持不变。

如果这些函数是否将 *t 中它们未直接设置的字段归零,则未指定:可移植程序应在调用 get() 之前将每个字段初始化为零。

[编辑] 示例

#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.

[编辑] 参见

(C++11)
解析指定格式的日期/时间值
(函数模板) [编辑]