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) | (since C++11) |
protected: virtual iter_type do_get( iter_type beg, iter_type end, std::ios_base& str, |
(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 中设置
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 中设置
目录 |
[编辑] 参数
beg | - | 指示要解析的序列的开头的迭代器 |
end | - | 要解析的序列的末尾迭代器之后的一个位置 |
str | - | 此函数用于在需要时获取区域设置侧面的流对象,例如 std::ctype 以跳过空格或 std::collate 以比较字符串 |
err | - | 流错误标志对象,此函数会修改该对象以指示错误 |
t | - | 指向 std::tm 对象的指针,该对象将保存此函数调用的结果 |
fmtbeg | - | 指向指定转换格式的 char_type 字符序列的第一个字符的指针(见下文) |
fmtend | - | 指向指定转换格式的 char_type 字符序列的最后一个字符之后的一个位置的指针 |
format | - | 命名转换说明符的字符 |
modifier | - | 可能出现在 % 和转换说明符之间的可选修饰符 |
格式字符串由零个或多个转换说明符、空格字符和普通字符(除了 %
)组成。 每个普通字符都应与输入流中的一个字符匹配(不区分大小写比较)。 每个空格字符都与输入字符串中的任意空格匹配。 每个转换规范都以 %
字符开头,可选地后跟 E
或 O
修饰符(如果区域设置不支持则忽略),后跟确定说明符行为的字符。 格式说明符与 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) |
解析指定格式的日期/时间值 (函数模板) |