std::time_get<CharT,InputIt>::get, std::time_get<CharT,InputIt>::do_get
来自 cppreference.cn
| 定义于头文件 <locale> |
||
| public: iter_type get( iter_type beg, iter_type end, std::ios_base& str, |
(1) | (C++11 起) |
| protected: virtual iter_type do_get( iter_type beg, iter_type end, std::ios_base& str, |
(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 中设置
eofbit 和 failbit。- 在循环体中,执行以下步骤:
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。- 首先,通过执行 err = std::ios_base::goodbit 清除 err 中的错误位。然后从输入序列 [beg, end) 中读取 std::time_get 格式说明符预期的字符,该格式说明符由 '%'、modifier(如果不是 '\0')和 format 组合而成。如果字符未组合成有效的转换说明符,则在 err 中设置
failbit。如果在读取字符后到达输入流的末尾,则在 err 中设置eofbit。如果输入字符串解析成功,则更新 *t 的相应字段。
- 首先,通过执行 err = std::ios_base::goodbit 清除 err 中的错误位。然后从输入序列 [beg, end) 中读取 std::time_get 格式说明符预期的字符,该格式说明符由 '%'、modifier(如果不是 '\0')和 format 组合而成。如果字符未组合成有效的转换说明符,则在 err 中设置
- 对于复杂的转换说明符,例如 '%x' 或 '%c',或使用修饰符 'E' 和 'O' 的指令,函数可能无法确定要存储在 *t 中的某些值。在这种情况下,它在 err 中设置
eofbit,并使这些字段处于未指定状态。
- 对于复杂的转换说明符,例如 '%x' 或 '%c',或使用修饰符 'E' 和 'O' 的指令,函数可能无法确定要存储在 *t 中的某些值。在这种情况下,它在 err 中设置
目录 |
[edit] 参数
| beg | - | 指定要解析序列起始的迭代器 |
| end | - | 要解析序列的结束迭代器之后一个位置 |
| str | - | 此函数在需要时用于获取区域设置 facet 的流对象,例如 std::ctype 用于跳过空格或 std::collate 用于比较字符串 |
| err | - | 由该函数修改以指示错误的流错误标志对象 |
| t | - | 指向将保存此函数调用结果的 std::tm 对象的指针 |
| fmtbeg | - | 指向指定转换格式(见下文)的 char_type 字符序列的第一个字符的指针 |
| fmtend | - | 指向指定转换格式的 char_type 字符序列的最后一个字符之后一个位置的指针 |
| format | - | 命名转换说明符的字符 |
| modifier | - | 可选的修饰符,可能出现在 % 和转换说明符之间 |
格式字符串由零个或多个转换说明符、空白字符和普通字符(除了 %)组成。每个普通字符应在不区分大小写的比较中与输入流中的一个字符匹配。每个空白字符匹配输入字符串中的任意空白。每个转换规范以 % 字符开头,可选地后跟 E 或 O 修饰符(如果区域设置不支持则忽略),然后是确定说明符行为的字符。格式说明符与 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) |
解析指定格式的日期/时间值 (函数模板) |