Namespaces
Variants

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

From cppreference.net
定义于头文件 <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 中同时设置 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
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 ,并将这些字段保留在未指定状态。

目录

参数

beg - 指向待解析序列起始位置的迭代器
end - 指向待解析序列结束位置后一位的迭代器
str - 流对象,本函数在需要时通过该对象获取本地化facet,例如用于跳过空白的 std::ctype 或用于字符串比较的 std::collate
err - 流错误标志对象,本函数通过修改该对象来指示错误状态
t - 指向 std::tm 对象的指针,用于保存本函数调用的解析结果
fmtbeg - 指向转换格式说明字符序列(详见下文)首字符的指针
fmtend - 指向转换格式说明字符序列末字符后一位的指针
format - 用于命名转换说明符的字符
modifier - 可选的修饰符,可能出现在 % 和转换说明符之间


格式字符串由零个或多个转换说明符、空白字符和普通字符(除 % 外)组成。每个普通字符需通过不区分大小写的比较与输入流中的一个字符匹配。每个空白字符可匹配输入字符串中的任意空白。每个转换规范以 % 字符开头,可选地后跟 E O 修饰符(若区域设置不支持则忽略),最后是决定说明符行为的字符。格式说明符与 POSIX 函数 strptime() 的规范一致:

转换
说明符
说明 写入字段
% 匹配字面量 % 。完整转换规范必须为 %% (无)
t 匹配任意空白字符 (无)
n 匹配任意空白字符 (无)
年份
Y 将完整 年份 解析为4位十进制数,允许但不要求前导零 tm_year
EY 以替代表示法解析 年份 ,例如在ja_JP区域设置中解析"平成23年"会将2011写入tm_year tm_year
y 年份 的后2位解析为十进制数。范围 [69,99] 对应1969-1999,范围 [00,68] 对应2000-2068 tm_year
Oy 使用替代数字系统解析 年份 后2位,例如在ja_JP区域设置中"十一"解析为11 tm_year
Ey 年份 解析为相对于区域设置替代日历周期 %EC 的偏移量 tm_year
C 年份 前2位解析为十进制数(范围 [00,99] tm_year
EC 解析区域设置替代表示法中的基准年(时期)名称,例如ja_JP中的"平成" 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年"而非"2011年" 全部
x 解析区域设置的标准日期表示 全部
Ex 解析区域设置的替代日期表示,例如在ja_JP区域设置中期望"平成23年"而非"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 等函数配合使用

返回值

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

注释

对于格式字符串中非空白且非 '%' 字符的大小写不敏感比较,通常(但不一定)使用由 str 提供的locale的 std::collate facet。

如果遇到解析错误,此函数的许多实现会保持 * 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)
解析指定格式的日期/时间值
(函数模板)