C语言时间操作
UNIX操作系统根据计算机产生的年代和应用采用1970年1月1日作为UNIX的纪元时间,1970年1月1日0点作为计算机表示时间的是中间点,将从1970年1月1日开始经过的秒数用一个整数存放,这种高效简洁的时间表示方法被称为“Unix时间纪元”,向左和向右偏移都可以得到更早或者更后的时间。
在实际开发中,对日期和时间的操作场景非常多,例如程序启动和退出的时间,程序执行任务的时间,数据生成的时间,数据处理的各环节的时间等,无处不在。
在学习时间之前,请把Linux操作系统的时区设置为中国上海时间。
一、time_t别名
在C语言中,用time_t来表示时间数据类型,它是一个long(长整数)类型的别名,在time.h文件中定义,表示一个日历时间,是从1970年1月1日0时0分0秒到现在的秒数。
1 | typedef long time_t; |
二、time库函数
time函数的用途是返回一个值,也就是从1970年1月1日0时0分0秒到现在的秒数。
time函数是C语言标准库中的函数,在time.h文件中声明。
1 | time_t time(time_t *t); |
time函数有两种调用方法:
1 | time_t tnow; |
或
1 | time(&tnow); // 将变量tnow的地址作为参数传递给time函数 |
您可以写代码测试一下这两种方式,效果完全相同。
三、tm结构体
time_t只是一个长整型,不符合我们的使用习惯,需要转换成可以方便表示时间的结构体,即tm结构体,tm结构体在time.h中声明,如下:
1 | struct tm |
这个结构定义了年、月、日、时、分、秒、星期、当年中的某一天、夏令时。用这个结构体可以很方便的显示时间。
四、localtime库函数
localtime函数用于把time_t表示的时间转换为struct tm结构体表示的时间,函数返回struct tm结构体的地址。
函数声明:
1 | struct tm * localtime(const time_t *); |
struct tm结构体包含了时间的各要素,但还不是我们习惯的时间表达方式,我们可以用格式化输出printf、sprintf或fprintf等函数,把struct tm结构体转换为我们想要的结果。
示例(book128.c)
1 | /* |
运行效果
五、mktime库函数
mktime函数的功能与localtime函数相反。
localtime函数用于把time_t表示的时间转换为struct tm表示的时间。
mktime 函数用于把struct tm表示的时间转换为time_t表示的时间。
1 | time_t mktime(struct tm *tm); |
函数返回time_t的值。
示例(book130.c)
1 | /* |
运行效果
六、程序睡眠
在实际开发中,我们经常需要把程序挂起一段时间,可以使用sleep和usleep两个库函数,需要包含unistd.h头文件中。函数的声明如下:
1 | unsigned int sleep(unsigned int seconds); |
sleep函数的参数是秒,usleep函数的参数是微秒,1秒=1000000微秒。
1 | sleep(1); // 程序睡眠1秒。 |
程序员不关心sleep和usleep函数的返回值。
七、精确到微秒的计时器
1、精确到微秒的timeval结构体
timeval结构体在sys/time.h文件中定义,声明为:
1 | struct timeval |
2、时区timezone 结构体
timezone 结构体在sys/time.h文件中定义,声明为:
1 | struct timezone |
3、gettimeofday库函数
gettimeofday是获得当前的秒和微秒的时间,其中的秒是指1970年1月1日到现在的秒,微秒是指当前秒已逝去的微秒数,可以用于程序的计时。调用gettimeofday函数需要包含sys/time.h头文件。
函数声明:
1 | int gettimeofday(struct timeval *tv, struct timezone *tz ) |
当前的时间存放在tv 结构体中,当地时区的信息则放到tz所指的结构体中,tz可以为空。
函数执行成功后返回0,失败后返回-1。
在使用gettimeofday()函数时,第二个参数一般都为空,我们一般都只是为了获得当前时间,不关心时区的信息。
示例(book132.c)
1 | /* |
运行效果
各位,book132.c程序采用usleep睡眠十分之一秒,但是计时器显示的实际时间大于十分之一秒,为何?原因很简单,因为程序执行需要时间,虽然这个时间很短,在千分之一秒内,那也是需要时间。
还有一个要注意的问题,time.h 是ISO C99 标准日期时间头文件。sys/time.h 是Linux系统的日期时间头文件,也就是说,timeval、timezone结构体和gettimeofday函数在windows平台中不能使用,真是麻烦。
八、应用经验
在实际开发中,除了当前的时间,还经常需要一个偏移量的时间,例如获取十分钟之后的时间,方法是采用time函数得到一个整数后,再加上10*60秒,再用localtime函数转换为结构体。
九、课后作业
继续丰富您的函数库。
1)编写一个通用函数,把整数的时间转换为字符串格式的时间,格式如:“2019-02-08
12:05:08”,如果转换成功函数返回0,失败返回-1,函数的声明如下:
1 | int timetostr(const time_t ti,char *strtime); |
2)编写一个通用函数,把字符串格式的时间转换为整数的时间,函数的声明如下:
1 | int strtotime(const char *strtime,time_t *ti); |
3)编写一个通用函数,获取操作系统的时间,函数的声明如下:
1 | void LocalTime(char *out_stime,const char *in_fmt,const int in_interval); |
out_stime是输出结果,格式由fmt决定。
in_interval是偏移常量,单位是秒。
in_fmt指定了out_stime的格式,取值如下:
1 | /* 常用的时间格式 |
调用示例:
1 | char strLocalTime[21]; |
十、版权声明
C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。
来源:C语言技术网(www.freecplus.net)
作者:码农有道