在 C/C++ 中,strftime() 和 strptime() 两个函数用于时间与字符串之间的转化,
它们都在头文件 time.h
或 ctime
中。
1. strftime() — 将 tm 时间结构体转为指定格式的时间字符串
函数声明如下
1 | size_t strftime (char *__restrict __s, size_t __maxsize, |
__s
: 存放转换后指定格式时间字符串的起始地址;__maxsize
: 可以在__s
写入字符串的最大长度(含末尾的\0
);__format
: 待写入__s
的格式化字符串;__tp
: 时间 tm 结构体的指针;- 返回值(
size_t
): 在__s
写入的字符串长度(不含\0
)。
下面用代码说明一下
1 |
|
输出
1 | the current time is 2021-09-06 23:50:13 |
2. strptime() — 将指定格式的时间字符串转为 tm 时间结构体
函数声明如下
1 | char *strptime (const char *__restrict __s, |
__s
: 待转换为 tm 结构体的时间字符串;__fmt
: 待读取的格式化字符串;__tp
: 时间 tm 结构体的指针,从字符串读取出来的时间信息会存到这里。- 返回值(
char *
): 指向__s
中第一个未匹配成功的字符,如果都匹配成功了的话,返回值是NULL
。
下面用代码说明一下,我们把上面的输出结果再转回去
1 |
|
输出
1 | Mon Sep 6 23:50:13 2021 |
注意我这里没输出任何其他内容,这是 asctime() 函数的默认输出格式,可以看到,这和 2021-09-06 23:50:13
是等价的(多了个 Mon 星期一)。
3. 综合示例:将一种时间格式的字符串转换为另一种时间格式的字符串
有一个很常见的场景是,我们要在 C/C++ 代码里得到一个时间字符串,但是有两种麻烦的情况:
- asctime() 和 ctime() 这种函数输出的时间格式不是我们想要的;
- 我们拿到的已经是一个现成的字符串,但时间格式不是我们想要的。
第一种情况,在上面 strptime() 的示例中已经解决了,这里主要说第二种情况。
场景:已有一个某种格式的时间字符串;
目标:将其转换为另一种格式的时间字符串。
这里假定我们已有一个比较混乱的时间字符串(举个例子弄乱点嘛) 2021年 Sep 6 Mon 23:50:13
,要把它转换为 2021-09-06 23:50:13
。
思路比较简单, 先用 strptime() 把比较混乱的时间字符串读到 tm 结构体里,再用 strftime() 得到我们想要的格式。
下面看代码
1 |
|
输出
1 | 2021-09-06 23:50:13 |
完工!
4. 说明符表
说明符 | 指代 | 示例 |
---|---|---|
%a |
Abbreviated weekday name * | Thu |
%A |
Full weekday name * | Thursday |
%b |
Abbreviated month name * | Aug |
%B |
Full month name * | August |
%c |
Date and time representation * | Thu Aug 23 14:55:02 2001 |
%C |
Year divided by 100 and truncated to integer (00-99 ) |
20 |
%d |
Day of the month, zero-padded (01-31 ) |
23 |
%D |
Short MM/DD/YY date, equivalent to %m/%d/%y |
08/23/01 |
%e |
Day of the month, space-padded (1-31 ) |
23 |
%F |
Short YYYY-MM-DD date, equivalent to %Y-%m-%d |
2001-08-23 |
%g |
Week-based year, last two digits (00-99 ) |
01 |
%G |
Week-based year | 2001 |
%h |
Abbreviated month name * (same as %b ) |
Aug |
%H |
Hour in 24h format (00-23 ) |
14 |
%I |
Hour in 12h format (01-12 ) |
02 |
%j |
Day of the year (001-366 ) |
235 |
%m |
Month as a decimal number (01-12 ) |
08 |
%M |
Minute (00-59 ) |
55 |
%n |
New-line character ('\n' ) |
`` |
%p |
AM or PM designation | PM |
%r |
12-hour clock time * | 02:55:02 pm |
%R |
24-hour HH:MM time, equivalent to %H:%M |
14:55 |
%S |
Second (00-61 ) |
02 |
%t |
Horizontal-tab character ('\t' ) |
`` |
%T |
ISO 8601 time format (HH:MM:SS ), equivalent to %H:%M:%S |
14:55:02 |
%u |
ISO 8601 weekday as number with Monday as 1 (1-7 ) |
4 |
%U |
Week number with the first Sunday as the first day of week one (00-53 ) |
33 |
%V |
ISO 8601 week number (01-53 ) |
34 |
%w |
Weekday as a decimal number with Sunday as 0 (0-6 ) |
4 |
%W |
Week number with the first Monday as the first day of week one (00-53 ) |
34 |
%x |
Date representation * | 08/23/01 |
%X |
Time representation * | 14:55:02 |
%y |
Year, last two digits (00-99 ) |
01 |
%Y |
Year | 2001 |
%z |
ISO 8601 offset from UTC in timezone (1 minute=1, 1 hour=100) If timezone cannot be determined, no characters | +100 |
%Z |
Timezone name or abbreviation * If timezone cannot be determined, no characters | CDT |
%% |
A % sign |
% |
* 用星号(*)标记的说明符依赖于语言环境。
注意: 橙色的行表示 C99 引入的说明符和子说明符。从 C99 开始,可以在百分比符号(%)和说明符之间插入两个特定于区域设置的修饰符来请求另一种格式,如果适用的话:
修饰符 | 含义 | 应用于 |
---|---|---|
E |
Uses the locale’s alternative representation | %Ec %EC %Ex %EX %Ey %EY |
O |
Uses the locale’s alternative numeric symbols | %Od %Oe %OH %OI %Om %OM %OS %Ou %OU %OV %Ow %OW %Oy |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 GuKaifeng's Blog!
评论(延迟加载 / 需要可访问 GitHub Issues)