《白话C++》第10章 STL和boost,Page194 10.10.1 C时间类型与操作

本文介绍了C语言中time_t数据类型、time()函数获取时间、tm结构与localtime函数的日期转换,以及clock()函数的计时特性,同时提到了C++新标准库和boost在时间处理中的应用,以及跨平台间的差异和陷阱。
摘要由CSDN通过智能技术生成

C时间类型与操作

在计算机中,计算时间,C语言扮演了一次上帝的角色,它说,让时间从1970年1月1日零点零分算起吧,用一个数据,存储这一起始点到当前总秒数这个数据的类型,称为“time_t”.

【小提示】:不精确的计时

C语言提供的计时,并不精确,因为它不主动处理科学上的“闰秒”现象,比如2012年6月30日23点59分59秒之后,并不是7月1号的第1秒,而是2012年6月30日23点59分60秒,然而C语言不理解这一秒。

1.  time_t:

“time_t”实际是一个类型别名(typedef),具体类型实现觉得,通常精度不小于整数类型。

当前使用32位GCC编译,time_t的size为4,换为64位GCC编译,则为8,这符合C/C++语言中“long”类型的长度规定;从C++11起,标准规定应为实数类型表达。后面为了同一,我们都使用32位版本。

2.  time(time_t*)函数

当下距离C语言的时间原点已经过去了多少秒?C语言提供了“time()”函数返回这个数值

time_t time(time_t *time);

入参是time_t的指针,出参也是time_t,但其实入参也是用来返回结果的,所以可以这样得到秒数

time_t seconds = 0;
time(&seconds);

 更直观和简便的做法,是传入空指针,通过返回值获得结果:

time_t seconds = time(nullptr);

例如:

cout << "距离1970年1月1日零点零分已经过去了:"
        << time(nullptr) << "秒。" << endl;

3.  tm结构和localtime函数

localtime函数,可以将前面提到的“秒数”,转换为具体的日历时间。(并且它会根据操作系统提供的时区进行调整,比如北京是东八区),日历时间使用名为“tm”的结构存储,它有如下成员数据:

struct tm
{
    int tm_sec; //秒[0,60],多数的1秒范围,可用于手工处理闰秒
    int tm_min; //分[0,59]
    int tm_hour;//小时[0,23]
    int tm_mday;//本月第几天[1,31],从1起,和生活中的日历一致
    int tm_mon; //月[0,11],对不起,它从0开始,和生活经验不一致
    int tm_year;//年,从1900年开始,而不是从1970年开始
    int tm_wday;//星期几,[0,6]从0开始,并且0代表星期天
    int tm_yday;//一年中第几天[0,365],同样从0开始。
    int tm_isdst;//1、0,表示是否夏时历,或为-1表示未知,中国不采用
};

对于一个东方人来讲,这个日期结构充满陷阱,所以一定要认真看各个成员的注释。

localtime函数声明如下:

tm* localtime(const time_t * time);

要知道现在是什么时候,可以先得到当前时间time_t,在将它转换为tm结构:

【课堂作业】:公历转农历

上网百度“C语言  公历  农历”,应该能搜索出不少使用C语言将公历日期转换为农历的代码。复制一份,阅读,理解,编译,并检查正确性。

4.  clock_t

clock()函数,返回当前程序启动后的计时。因为关注的“历史”变短,所以关注的精度得以提高。

它返回的整数,代表当前程序本次启动之后的“CPU时间”。不过,根据平台不同,这里的“CPU时间”所指的真实含义,大有不同,这一点必须注意,特别是编写跨平台程序时。

“clock”的字面意思(你可以把这个词当成“象声词”理解),是时钟的又一次“滴答”,有些人认为时钟一次滴答不就是一秒吗?这个可不一定,石英钟或许如此,老式座钟滴答几次才一秒,是需要物理学计算的。

到了操作系统,Windows环境(包括mingw环境)下滴答1000次才一秒,而在Linux环境下滴答

1 000 000 次才是1秒,显然Linux追求更高的精度。

【危险】:Windows和Linux下,clock()的关键差异

有关不同操作系统,规定一秒钟到底包含多少次“clock”的差异,只许通过一个宏“CLOCKS_PER_SEC”即可解决,真正让人“摔跟斗”的差异是同样调用clock()Windows返回的是程序启动到现在的时间,和CPU其实无关,而Linux返回的程序启动到现在它所占用的CPU计算时间

想想同一时刻里,你的电脑前台或后台中在运行的程序,可能上百个,而你的CPU可能就四核或八核,所以Linux下clock()返回的数值,将远远小于Windows下的值。

clock()最常用来计时某段代码的运行时长,我们曾经拿它对比过vector和list的插入性能。今天又知道它在不同操作系统下的关键差异。

不过有关clock()函数还有个危险点,那就是虽然它通常和time_t是同一类型的别名(比如long),但由于它对精度要求高,所以容易溢出。

以32位Windows为例,clock_t使用long(有符号)表达,因此最大值是(2的31次方 - 1),因此程序连续运行24.855 134 803天之后clock()返回值即溢出。

【课堂作业】:亲眼目睹clock_t的溢出

写一段出程序,前后两次获取clock()返回值,并想办法让第二次所得到的值溢出(打印到屏幕是负数)——办法之一是开个程序不退出,再加不关机等它25天。

长期以来,C++程序员都直接使用C标准函数处理日期时间,它们的接口简单直接,但也有着这样或那样的陷阱,为此,下面介绍C++新标准库以及boost提供的多项时间操作。

  • 16
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值