另外参见

date(1),time(2),ctime(3),nl_langinfo(3),setlocale(3),sprintf(3),strptime(3)

说明

strftime()函数根据格式规范格式对分解时间tm进行格式化,并将结果放入大小为max的字符数组s中。细分的时间结构tm在中定义。另请参见ctime(3)。

格式规范是一个以空字符结尾的字符串,并且可以包含称为转换规范的特殊字符序列,每个字符序列均由aq%aq字符引入,并由称为转换说明符的某些其他字符终止。所有其他字符序列都是普通字符序列。

普通字符序列的字符(包括空字节)被逐字从格式复制到s。但是,转换规范的字符已替换,如下表所示。在此列表中,还显示了从tm结构采用的字段。

%a
根据当前语言环境的星期几的缩写名称。 (从tm_wday计算。)(可以通过以ABDAY_ {1-7}作为参数调用nl_langinfo(3)来获得当前语言环境中使用的特定名称。)
%A
根据当前语言环境的星期几的全名。 (从tm_wday计算。)(可以通过将DAY_ {1-7}作为参数调用nl_langinfo(3)来获得当前语言环境中使用的特定名称。)
%b
根据当前语言环境的缩写月份名称。 (从tm_mon计算。)(可以通过以ABMON_ {1-12}作为参数调用nl_langinfo(3)来获得当前语言环境中使用的特定名称。)
%B
根据当前语言环境的完整月份名称。 (根据tm_mon计算。)(可以通过将MON_ {1-12}作为参数调用nl_langinfo(3)来获得当前语言环境中使用的特定名称。)
%c
当前语言环境的首选日期和时间表示形式。 (当前语言环境中使用的特定格式可以通过调用nl_langinfo(3)来获取,其中D_T_FMT作为参数用于%c转换规范,而ERA_D_T_FMT作为%Ec转换规范。)(在POSIX语言环境中,这等效于%a%b%e%H:%M:%S%Y。)
%C
世纪数字(年/ 100)为2位整数。 (SU)(%EC转换规范对应于时代的名称。)(根据tm_year计算。)
%d
以十进制数字表示的月份中的日期(范围为01到31)。 (根据tm_mday计算。)
%D
相当于%m /%d /%y。 (Yecch-仅适用于美国人。美国人应注意,在其他国家/地区,%d /%m /%y很常见。这意味着在国际范围内,这种格式是模棱两可的,不应使用。)
%e
像%d一样,一个月的日期是一个十进制数字,但是前导零被空格代替。 (SU)(根据tm_mday计算。)
%E
修饰符:使用替代("基于时代")格式,请参见下文。 (SU)
%F
等效于%Y-%m-%d(ISO8601日期格式)。 (C99)
%G
基于世纪的ISO8601年(请参阅注释),以世纪作为十进制数字。与ISO周编号相对应的4位数字的年份(请参见%V)。它的格式和值与%Y相同,不同的是,如果ISO周编号属于上一年或下一年,则改用该年份。 (TZ)(根据tm_year,tm_yday和tm_wday计算。)
%g
类似于%G,但没有世纪,即具有两位数的年份(00-99)。 (TZ)(根据tm_year,tm_yday和tm_wday计算。)
%h
等效于%b。 (SU)
%H
使用24小时制的小时(十进制数)(范围为00至23)。 (根据tm_hour计算。)
%I
使用12小时制(范围为01至12)的小时作为十进制数字。 (根据tm_hour计算。)
%j
一年中的天,以十进制数字表示(范围为001至366)。 (根据tm_yday计算。)
%k
小时(24小时制)为十进制数字(范围为0到23);单个数字后跟一个空格。 (另请参阅%H。)(根据tm_hour计算。)(TZ)
%l
小时(12小时制)为十进制数字(范围为1到12);单个数字后跟一个空格。 (另请参见%I。)(根据tm_hour计算。)(TZ)
%m
以十进制数字表示的月份(范围为01到12)。 (根据tm_mon计算。)
%M
分钟,十进制数字(范围为00到59)。 (根据tm_min计算。)
%n
换行符。 (SU)
%O
修饰符:使用其他数字符号,请参见下文。 (SU)
%p
根据给定的时间值,使用" AM"或" PM",或者使用当前语言环境的相应字符串。中午被视为" PM",午夜被视为" AM"。 (从tm_hour计算。)(可以通过分别使用AM_STR和PM_STR调用nl_langinfo(3)来获取当前语言环境中用于" AM"和" PM"的特定字符串表示形式。)
%P
类似于%p,但小写:" am"或" pm"或当前语言环境的相应字符串。 (根据tm_hour计算。)(GNU)
%r
上午或下午的时间符号。 (SU)(当前语言环境中使用的特定格式可以通过使用T_FMT_AMPM作为参数调用nl_langinfo(3)来获得。)(在POSIX语言环境中,这等效于%I:%M:%S%p。)
%R
以24小时制表示的时间(%H:%M)。 (SU)有关包含秒数的版本,请参见下面的%T。
%s
自1970年1月1日00:00:00 +0000(UTC)以来的秒数。 (TZ)(根据mktime(tm)计算。)
%S
第二个十进制数字(范围为00到60)。 (该范围最大为60,以允许偶尔出现leap秒。)(根据tm_sec计算。)
%t
制表符。 (SU)
%T
以24小时制表示的时间(%H:%M:%S)。 (SU)
%u
以十进制表示的星期几,范围为1到7,星期一为1。另请参见%w。 (从tm_wday计算。)(SU)
%U
当前年份的星期数,以十进制数表示,范围为00到53,从第一个星期日作为第01周的第一天开始。另请参见%V和%W。 (根据tm_yday和tm_wday计算。)
%V
当前年份的ISO8601周号(请参阅注释)为十进制数字,范围为01至53,其中第1周是新年中至少有4天的第一周。另请参见%U和%W。 (根据tm_year,tm_yday和tm_wday计算。)(SU)
%w
以十进制表示的星期几,范围为0到6,星期日为0。另请参见%u。 (根据tm_wday计算。)
%W
当前年份的星期数,以十进制数表示,范围为00到53,从第一个星期一作为第01周的第一天开始。(从tm_yday和tm_wday计算)。
%x
当前语言环境的首选日期表示形式,没有时间。 (当前语言环境中使用的特定格式可以通过调用nl_langinfo(3)来获取,其中D_FMT作为参数用于%x转换规范,而ERA_D_FMT作为%Ex转换规范。) %m /%d /%y。)
%X
当前区域设置的首选时间表示形式,不带日期。 (当前语言环境中使用的特定格式可以通过调用nl_langinfo(3)来获取,其中T_FMT作为参数用于%X转换规范,而ERA_T_FMT作为%EX转换规范。) %H:%M:%S。)
%y
年份,不带世纪的十进制数字(范围为00到99)。 (%Ey转换规范对应于%EC转换规范表示的时代开始以来的年份。)(根据tm_year计算)
%Y
以十进制数字表示的年份,包括世纪。 (%EY转换规范对应于完整的替代年份表示。)(根据tm_year计算)
%z
+ hhmm或-hhmm数字时区(即距UTC的小时和分钟偏移量)。 (SU)
%Z
时区名称或缩写。
%+
date(1)格式的日期和时间。 (TZ)(glibc2不支持。)
%%
文字aq%aq字符。

可以通过在转换说明符前面加上E或O修饰符来修改某些转换规范,以指示应使用替代格式。如果当前语言环境不存在替代格式或规范,则其行为将类似于使用未修改的转换规范。 (SU)单一UNIX规范提到了%Ec,%EC,%Ex,%EX,%Ey,%EY,%Od,%Oe,%OH,%OI,%Om,%OM,%OS,%Ou, %OU,%OV,%Ow,%OW,%Oy,其中O修饰符的作用是使用替代数字符号(例如,罗马数字),而E修饰符的作用是使用与语言环境相关的替代表示形式。通过使用ERA作为nl_langinfo(3)的参数,可以获得使用E修饰符控制日期表示的规则。这种替代形式的一个示例是ja_JP glibc语言环境中的日语时代日历方案。

BUGS

如果输出字符串超过最大字节数,则不会设置errno。这使得无法将这种错误情况与格式字符串合法产生零长度输出字符串的情况区分开。 POSIX.1-2001没有为strftime()指定任何errno设置。

gcc(1)的某些错误版本抱怨使用%c:警告:在某些语言环境中,%caq仅产生年份的后两位数字。当然,鼓励程序员使用%c,因为它提供了首选的日期和时间表示。人们遇到各种奇怪的困惑来规避此gcc(1)问题。一个相对干净的是添加一个中间功能

size_t
my_strftime(char *s, size_t max, const char *fmt,
            const struct tm *tm)
{
    return strftime(s, max, fmt, tm);
}

如今,gcc(1)提供了-Wno-format-y2k选项来防止警告,因此不再需要上述解决方法。

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
strftime()Thread safetyMT-Safe env locale
STRFTIME - Linux手册页

Linux程序员手册 第3部分
更新日期: 2020-08-13

示例

符合RFC 2282的日期格式(具有%a和%b的英语语言环境)

"%a,%d%b%Y %% T%z"

符合RFC 822的日期格式(%a和%b的英语语言环境)

"%a,%d%b%yy%T%z"

Example program

下面的程序可用于尝试strftime()。

由glibc实现的strftime()生成的结果字符串的一些示例如下:

$ ./a.out aq%maq
Result string is "11"
$ ./a.out aq%5maq
Result string is "00011"
$ ./a.out aq%_5maq
Result string is "   11"

Program source

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    char outstr[200];
    time_t t;
    struct tm *tmp;

    t = time(NULL);
    tmp = localtime(&t);
    if (tmp == NULL) {
        perror("localtime");
        exit(EXIT_FAILURE);
    }

    if (strftime(outstr, sizeof(outstr), argv[1], tmp) == 0) {
        fprintf(stderr, "strftime returned 0");
        exit(EXIT_FAILURE);
    }

    printf("Result string is \"%s\"\n", outstr);
    exit(EXIT_SUCCESS);
}

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

环境

使用环境变量TZ和LC_TIME。

返回值

假设结果字符串(包括终止空字节)不超过最大字节,则strftime()返回放置在数组s中的字节数(不包括终止空字节)。如果结果字符串的长度(包括终止的空字节)将超过最大字节,则strftime()返回0,并且数组的内容未定义。

请注意,返回值0不一定表示错误。例如,在许多语言环境中,%p产生一个空字符串。空格式字符串将同样产生一个空字符串。

备注

ISO 8601 week dates

从ISO8601标准定义的以周为基础的年份计算得出的%G,%g和%V屈服值。在此系统中,周从星期一开始,从第一周的01开始编号,最后一周从52或53开始编号。第一周是新年中四天或四天以上的第一周(或者,周01是:一年中的第一周,其中包含一个星期四;或者,其中包含1月4日的那一周)。当新的一年的第一个日历周的三天或更少天属于该年时,则基于ISO 8601周的系统会将这些天计为上一年的第52周或第53周。例如,2010年1月1日是星期五,这意味着该日历周中只有三天属于2010年。因此,基于ISO8601的周系统将这些天视为2009年第53周(%V)的一部分( %G); ISO8601年2010年的第01周从2010年1月4日星期一开始。同样,2011年1月的前两天被视为2010年第52周的一部分。

Glibc notes

Glibc为转换规范提供了一些扩展。 (在POSIX.1-2001中未指定这些扩展名,但是其他一些系统提供了类似的功能。)在aq%aq字符和转换说明符之间,可以指定可选的标志和字段宽度。 (如果存在,则在E或O修饰符之前。)

允许使用以下标志字符:

_
(下划线)用空格填充数字结果字符串。
-
(破折号)请勿填充数字结果字符串。
0
即使转换说明符字符默认情况下使用空格填充,也要用零填充数字结果字符串。
ha
将结果字符串中的字母字符转换为大写。
#
交换结果字符串的大小写。 (此标志仅适用于某些转换说明符,其中只有%Z才真正有用。)

可选的十进制宽度说明符可以位于(可能不存在)标志之后。如果字段的自然大小小于此宽度,则将结果字符串填充(在左侧)为指定宽度。

语法

#include <time.h>

size_t strftime(char *s, size_t max, const char *format,
                const struct tm *tm);

名称

strftime-格式化日期和时间

遵循规范

SVr4,C89,C99。在ANSI C(未标记),单一UNIX规范(标记为SU),Olson时区软件包(标记为TZ)和glibc(标记为GNU)中给出的转换之间,存在严格的转换,除了glibc2不支持%+之外。另一方面,glibc2还有更多扩展。 POSIX.1仅指ANSIC。 POSIX.2在date(1)下描述了一些扩展名,这些扩展名也可以应用于strftime()。 %F转换在C99和POSIX.1-2001中进行。

在SUSv2中,%S指示符允许范围为00到61,以允许理论上包括一秒钟的leap秒的分钟的可能性(从来没有这样的分钟)。

日期:2019-08-20 18:01:24 来源:oir作者:oir