热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C/C++常用时间函数介绍

在介绍之前,先介绍两个概念CoordinatedUniversalTime(UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(GreenwichMea

在介绍之前,先介绍两个概念

 

Coordinated Universal Time(UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean Time,GMT)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。

 

Calendar Time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是“相对时间”,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。(简单点说,可以理解为CT时间就是 UTC时间减去1900-01-01 00:00:00)

 

与日期和时间相关的数据结构

 

Cpp代码  收藏代码
  1. typedef long time_t          

 

    大家可能会产生疑问:既然time_t实际上是长整型,到未来的某一天,从一个时间点(一般是1970年1月1日0时0分0秒)到那时的秒数(即日历时间)超出了长整形所能表示的数的范围怎么办?对time_t数据类型的值来说,它所表示的时间不能晚于2038年1月18日19时14分07秒。为了能够表示更久远的时间,一些编译器厂商引入了64位甚至更长的整形数来保存日历时间。比如微软在Visual C++中采用了__time64_t数据类型来保存日历时间,并通过_time64()函数来获得日历时间(而不是通过使用32位字的time()函数),这样就可以通过该数据类型保存3001年1月1日0时0分0秒(不包括该时间点)之前的时间。

 

Cpp代码  收藏代码
  1. struct tm   
  2.   
  3.     int tm_sec;    
  4.     int tm_min;    
  5.     int tm_hour;    
  6.     int tm_mday;   
  7.     nt tm_mon;    
  8.     int tm_year;     
  9.     int tm_wday;    
  10.     int tm_yday;    
  11.     int tm_isdst;    
  12. };  

 

Cpp代码  收藏代码
  1. typedef long clock_t    "开启这个程序进程""程序中调用clock()函数"时之间的CPU时钟计时单元(clock tick)数  

 

clock(取得CPU时钟计时单元(clock tick)数)
函数定义
clock_t clock( void )


函数说明
函数返回从"开启这个程序进程"到"程序中调用clock()函数"时之间的CPU时钟计时单元(clock tick)数。其中clock_t是用来保存时间的数据类型


返回值
从"开启这个程序进程"到"程序中调用clock()函数"时之间的CPU时钟计时单元(clock tick)数

 

在time.h文件中,定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:

#define CLOCKS_PER_SEC ((clock_t)1000)

可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。

 

范例:

Cpp代码  收藏代码
  1. #include "stdio.h"  
  2. #include "time.h"  
  3.   
  4. int main( void  
  5.  
  6.    long    10000000L;  
  7.    clock_t start, end;  
  8.    double  timeUsed;  
  9.    start clock();  
  10.    whilei--       
  11.    end clock();  
  12.    timeUsed (double)(end start) CLOCKS_PER_SEC;  
  13.    printf( "执行10000000次空循环用时%f秒\n"timeUsed );  
  14.  

 

输出结果
    执行10000000次空循环用时0.031000秒

 

time(取得目前的时间)
函数定义
time_t time(time_t *t);


函数说明
此函数会返回从公元1970年1月1日的0时0分0秒算起到现在所经过的秒数(CT时间)。如果t是非空指针的话,此函数也会将返回值存到t指针所指的内存。


返回值
成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno中。

 

注意:由于返回的是CT时间,所以在做时间判断的时候一定要注意时区

 

范例

Cpp代码  收藏代码
  1. #include   
  2. #include   
  3.   
  4. #define DAY_SECONDS (24*60*60)  
  5.   
  6. int main(int argc, char**argv)  
  7.  
  8.     time_t timeNow time(NULL);  
  9.   
  10.     time_t timeDayNow  timeNowY_SECONDS;  
  11.     int hour timeDayNow/3600;  
  12.     int min (timeDayNow600)/60;  
  13.     int sec timeDayNow`;  
  14.   
  15.     printf("现在时间%d:%d:%d\n"hour, min, sec);   
  16.   
  17.     return 0;  
  18. };  

 

输出结果会比你当前系统的时间早8个小时,那是因为中国内地的时间与UTC的时差为+8

 


localtime(取得当地目前时间和日期)
函数定义
struct tm *localtime(const time_t * timep);


函数说明
将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。结构tm的定义请参考上面。此函数返回的时间日期已经转换成当地时区。


返回值
返回结构tm代表目前的当地时间。

 

gmtime(取得当地目前时间和日期)
函数定义
struct tm *gmtime()(const time_t * timep);


函数说明
将日历时间转化为世界标准时间(即格林尼治时间),并返回一个tm结构体来保存这个时间


返回值
返回结构tm代表目前的当地时间。

 

上面这个两个函数的参数和返回值都一样,唯一区别是localtime做了时区处理,返回当前时区的时间,而gmtime返回UTC时间

 

范例

Cpp代码  收藏代码
  1. #include   
  2. #include   
  3.   
  4. int main(int argc, char**argv)  
  5.  
  6.     const char *wday[]={"星期天","星期一","星期二","星期三","星期四","星期五","星期六"};   
  7.   
  8.     time_t timeNow time(NULL);  
  9.   
  10.     struct tmlocaltime(&timeNow);   
  11.   
  12.     struct tmpp;  
  13.   
  14.     printf("%d年%d月%d日 %d:%d:%d %s\n",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec, wday[p->tm_wday]);   
  15.   
  16.     pp gmtime(&timeNow);  
  17.   
  18.     printf("%d年%d月%d日 %d:%d:%d %s\n",pp->tm_year+1900,pp->tm_mon+1,pp->tm_mday,pp->tm_hour,pp->tm_min,pp->tm_sec, wday[pp->tm_wday]);   
  19.   
  20.     return 0;  
  21. };  

 

输出结果
2010年4月1日 15:16:22 星期四
2010年4月1日 7:16:22 星期四


  其中localtime的结果和当前系统时间相同,gmtime比当前时间少8个小时

 

  注意:由于localtime和gmtime都使用全局变量存储结果,所以在使用时一定要注意,特别是在多线程中,他们都不是线程安全的函数


范例

Cpp代码  收藏代码
  1. #include   
  2. #include   
  3.   
  4. int main(int argc, char**argv)  
  5.  
  6.     time_t timeNow time(NULL);  
  7.     struct tm *p localtime(&timeNow);   
  8.   
  9.     struct tm *pp;  
  10.     timeNow += 10000;  
  11.     pp localtime(&timeNow);  
  12.   
  13.     printf("当前时间:%d年%d月%d日 %d:%d:%d\n",p->tm_year+1900,p->tm_mon+1,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec );   
  14.     printf("相加后时间:%d年%d月%d日 %d:%d:%d\n",pp->tm_year+1900,pp->tm_mon+1,pp->tm_mday,pp->tm_hour,pp->tm_min,pp->tm_sec );   
  15.   
  16.     return 0;  
  17. };  

 

输出:
当前时间:2010年4月1日 18:42:46
相加后时间:2010年4月1日 18:42:46


虽然后面的时间加了10000秒,但由于他们共用同样的全局变量,所以两个的时间是一样的

 

mktime(将时间结构数据转换成经过的秒数)

函数定义
time_t mktime(strcut tm * timeptr);


函数说明
mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0 秒算起至今的UTC时间所经过的秒数。


返回值
返回经过的秒数。


注意:这里传入的参数必须是本地时间,不然就乱了

 

范例

Cpp代码  收藏代码
  1. #include   
  2. #include   
  3.   
  4. int main(int argc, char**argv)  
  5.  
  6.     time_t timeNow time(NULL);  
  7.   
  8.     struct tmlocaltime(&timeNow);   
  9.   
  10.     time_t timeNow1 mktime(p);   
  11.   
  12.     struct tmpp gmtime(&timeNow);  
  13.   
  14.     time_t timeNow2 mktime(pp);  
  15.   
  16.     printf("%ld\n%ld\n%ld\n"timeNow, timeNow1, timeNow2);  
  17.   
  18.     return 0;  
  19. };  

 

输出结果
1270106860
1270106860
1270078060


可以发现当传UTC时间给mktime的时候,就还原不回去了,会比当前时间少28800秒,刚好8个小时

 


夏令时间
    夏令时比标准时快一个小时。例如,在夏令时的实施期间,标准时间的上午10点就成了夏令时的上午11点。


 夏令时,又称“日光节约时制”或“夏时制”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏令时的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。(各时区多数位于其理想边界之西,导致实际上全年实施夏令时。),中国现在已经不实行夏令时

 

范例

Cpp代码  收藏代码
  1. #include   
  2. #include   
  3.   
  4. int main(int argc, char**argv)  
  5.  
  6.     time_t timeNow time(NULL);  
  7.   
  8.     struct tm *(localtime(&timeNow));   
  9.     struct tm pp p;  
  10.   
  11.     printf("当前时间:%ld\n"mktime(&p));  
  12.   
  13.     pp.tm_isdst 1;  
  14.   
  15.     printf("启动夏令时后的时间:%ld\n"mktime(&pp));  
  16.   
  17.     return 0;  
  18. };  

 
输出:
当前时间:1270109197
启动夏令时后的时间:1270109197

 

从这里的输出发现,设置这个值好像没什么用处,同时我试了下调试运行,发现执行了mktime(&pp)后,pp中的tm_isdst又等于0了
暂时没发现tm_isdst变量的实际用途


还有一点要注意,struct tm结构体中字段tm_mday的值是从1开始,所以在构造月初时间的时候一定要把这个字段置为1

Cpp代码  收藏代码
  1. #include   
  2. #include   
  3.   
  4. int main(int argc, char**argv)  
  5.  
  6.     time_t timeNow time(NULL);  
  7.     struct tm *p localtime(&timeNow); //取得当前时间  
  8.   
  9.     struct tm pp;  
  10.     memset(&pp, '\0'sizeof(pp));  
  11.     pp.tm_year p->tm_year;  
  12.     pp.tm_mon p->tm_mon;//设置成了当前月  
  13.       
  14.     time_t timePP mktime(&pp);  
  15.   
  16.     printf("时间:%d年%d月%d日 %d:%d:%d\n",pp.tm_year+1900,pp.tm_mon+1,pp.tm_mday,pp.tm_hour,pp.tm_min,pp.tm_sec );   
  17.   
  18.     return 0;  
  19. };  

 
输出结果:时间:2010年3月31日 0:0:0

 

我们期待的输出是“2010年4月1日 0:0:0”,但由于pp.tm_mday等于0,所以最后得到的时间timePP是上个月月底,相差了一天,正确的做法是设置pp.tm_mday等于1


推荐阅读
  • 在C++程序中,文档A的每一行包含一个结构体数据,其中某些字段可能包含不同数量的数字。需要将这些结构体数据逐行读取并存储到向量中,随后不仅在控制台上显示,还要输出到新创建的文档B中。希望得到指导,感谢! ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 本文介绍如何使用OpenCV和线性支持向量机(SVM)模型来开发一个简单的人脸识别系统,特别关注在只有一个用户数据集时的处理方法。 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 本文介绍如何使用线段树解决洛谷 P1531 我讨厌它问题,重点在于单点更新和区间查询最大值。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 题目《BZOJ2654: Tree》的时间限制为30秒,内存限制为512MB。该问题通过结合二分查找和Kruskal算法,提供了一种高效的优化解决方案。具体而言,利用二分查找缩小解的范围,再通过Kruskal算法构建最小生成树,从而在复杂度上实现了显著的优化。此方法不仅提高了算法的效率,还确保了在大规模数据集上的稳定性能。 ... [详细]
  • 类加载机制是Java虚拟机运行时的重要组成部分。本文深入解析了类加载过程的第二阶段,详细阐述了从类被加载到虚拟机内存开始,直至其从内存中卸载的整个生命周期。这一过程中,类经历了加载(Loading)、验证(Verification)等多个关键步骤。通过具体的实例和代码示例,本文探讨了每个阶段的具体操作和潜在问题,帮助读者全面理解类加载机制的内部运作。 ... [详细]
  • 你的问题在于:1. 代码格式混乱,缺乏必要的缩进,导致可读性极低;2. 使用 `strlen()` 和 `malloc()` 函数时,必须包含相应的头文件;3. `write()` 函数的返回值处理不当,建议检查并处理其返回值以确保程序的健壮性。此外,建议在编写代码时遵循良好的编程规范,增加代码的可维护性和可读性。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
author-avatar
大小大空间_566
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有