6.10 时间和日期例程

6.10 时间和日期例程

UNIX内核提供的基本时间服务是计算处国际标准时间公元1970年1月1日00:00:00以来经过的秒数,它是用数据类型time_t表示的,我们称其为日历时间:包括日期和时间。Unix在这方面与其它操作系统的区别是(a)以国际标准时而非本地时间计时,(b)可自动进行转换,例如变换到夏日制,(c)将时间和日期作为一个量值保存。

time函数可以返回当前时间和日期:

#include <time.h>

time_t time(time_t *calptr);


与time函数相比,gettimeofday提供了更高的分辨率(最高为微秒级):

#include <sys/time.h>

int gettimeofday(struct timeval *restrict tp, void *restrict tzp);

其中,结构timeval定义如下:

struct timeval{

time_t tv_sec;

long tv_usec; /*microseconds*/

};


一旦获得这种以秒计的整型时间值后,通常要调用另一个时间函数将其转换为人们可读的时间和日期,下图说明了各个函数之间的关系:(下述函数中localtime、mktime、ctime和strftime都收到环境变量TZ的影响)

clip_image002

两个函数localtime和gmtime将日历时间转换成以年、月、日、时、分、秒、周日表示的时间,并将这些存放在一个tm结构,tm定义如下(注意每个成员的范围):

struct tm{ /*a broken-down time*/

int tm_sec; //seconds after the minute:[0-60]

int tm_min; //minutes after the hour:[0-59]

int tm_hour; /*hours after midnight:[0-23]*/

int tm_mday; /*day of the month[1-31]*/

int tm_mon; /*months since January[0-11]*/

int tm_year; /*years since 1900*/

int tm_wday; /*days since Sunday:[0-6]*/

int tm_yday; /*days since January 1:[0-365]*/

int tm_isdst; /*datlight saving time flag:<0,0,>0*/

};


秒可以超过59的理由是可以表示润秒。注意,除了月日字段,其它字段的值都以0开始。如果夏日制生效,则夏日制标志值为正,如果已非夏日制时间则为零,如果此信息不可用,则为负。

#include <time.h>

struct tm *gmtime(const time*_t calptr) ;

struct tm *localtime(const time_t calptr*) ;

两个函数返回:指向t m结构的指针

localtime和gmtime之间的区别是:localtime将日历时间变换成本地时间(考虑到本地时区和夏日制标志),而gmtime则将日历时间变换成国际标准时的年、月、日、时、分、秒、周日。

函数mktime以本地时间的年、月、日等作为参数,将其变换成time_t值。

#include <time.h>

time_t mktime(struct tm *tmptr);//返回:若成功为日历时间,出错为-1

asctime和ctime函数产生下列形式的26字节字符串,这与date(1)命令的系统默认输出形式类似:

Tue Jan 14 17:49:03 1992\n\0

#include <time.h>

char *asctime(const struct *tm tmptr) ;

char *ctime(const time_t *calptr) ;

两个函数返回:指向n u l l结尾的字符串

asctime的参数是指向年、月、日等字符串的指针,而ctime的参数则是指向日历时间的指针。

最后一个时间函数是strftime,它是非常复杂的printf类的时间值函数。

#include <time.h>

size_t strftime(char *buf,size_t maxsize,const char *format,const struct tm *tmptr);
// 返回:若有空间为存入数组的字符数,否则为0


最后一个参数是要格式化的时间值,说明为指向一个年、月、日、时、分、秒、周日时间值的指针。格式化结果存放在一个长度为maxsize个字符的buf数组中,如果buf长度是以存放格式化结果及一个null络止符,则该函数返回在buf中存放的字符数(不包括null终止符)。否则该函数返回0。

format参数控制时间值的格式。如同printf函数一样,变换说明的形式是百分号之后跟一个特定字符。在format中的其它字符则按原择输出。两个连续的百分号在输出中产生一个百分号。与printf函数的不同之处是,每个变换说明产生一个定长输出字符串,在format字符串中没有宽字段修饰符,表中列出了37种ISO C规定的变换说明。

格式

说明

实例

%a

缩写的星期名

Thu

%A

全星期名

Thursday

%b

缩写的月名

Aug

%B

全月名

August

%c

日期和时间

Thu Aug 23 14:55:02 2001

%C

年/100 [00,99]

20

%d

十进制表示的每月的第几天 [01,31]

16

%D

月/天/年 [MM/DD/YY]

06/16/12

%e

十进制表示的每月的第几天 ,一位数前加空格[1,31]

10

%F

年-月-日 [YYYY-MM-DD]

2012-06-16

%g

ISO 8601使用基于周的年的后两位数字

12

%G

ISO 8601使用基于周的年

2012

%h

简写的月份名 ,与%b相同

Aug

%H

24小时制的小时 [00,23]

14

%I

12小时制的小时 [01,12]

02

%j

每年的第几天 [001,366]

235

%m

十进制的月 [01,12]

08

%M

分钟 [00,59]

55

%n

换行符

 

%p

AM/PM

PM

%r

本地时间:(12时制)

11:01:23 AM

%R

与“%H:%M”相同

11:01

%S

秒 [00,60]

02

%t

水平制表符

 

%T

与“%H:%M:%S”相同

11:01:23

%u

ISO 8601的星期,星期一为1,[1,7]

2

%U

周数 ,以周日为一周开始 [00,53]

33

%V

ISO 8601周数 [01,53]

07

%w

星期,星期天为0. [0,6]

4

%W

周数,以星期一为一周开始 [00,53]

34

%x

标准日期

06/16/12

%X

标准时间

14:55:02

%y

年份的后两位数字 [00,99]

12

%Y

2012

%z

ISO 8601格式的UTC偏移量

-0500

%Z

时区名

EST

%%

百分号

%

图中的大多数格式说明的意义是很明显的。需要略作解释的是%U和%W。%U是相应日期在该年中所属周数,包含该年中第一个星期日的周是第一周。%W也是相应日期在该年中所属的周数,不同的是包含第一个星期一的周为第一周。而%V说明符则与上述两者有较大区别。若某周包含了1月1日,而且至少包含了其后的另外3天,那么改周是一年中的第一周,否则改周被认为是上一年的最后一周。在这两种情况下,周一都被视为每周的第一天。

原文地址:https://www.cnblogs.com/shaoguangleo/p/2805999.html