`
strong_fee
  • 浏览: 178775 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

C、C++中的日期和时间 time_t与struct tm转换

阅读更多

一.概念
Coordinated Universal Time
UTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean TimeGMT)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5
Calendar Time
日历时间,是用从一个标准时间点到此时的时间经过的秒数来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是相对时间,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。
epoch
时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。
clock tick
时钟计时单元(而不把它叫做时钟滴答次数),一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。
二. 计时
1.    clock: C/C++
中的计时函数是clock(),而与其相关的数据类型是clock_t。在MSDN中,查得对clock函数定义如下:
clock_t clock( void );
返回:从开启这个程序进程程序中调用clock()函数时之间的CPU时钟计时单元(clock tick)数。

clock_t:是用来保存时间的数据类型,在time.h文件中,我们可以找到对它的定义:
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif

2. CLOCKS_PER_SEC      
time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:
#define CLOCKS_PER_SEC ((clock_t)1000)
可以看到可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。下面举个例子,你可以使用公式clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间:
void elapsed_time()
{
printf("Elapsed time:%u secs.\n",clock()/CLOCKS_PER_SEC);
}

3.    clock计时
当然,你也可以用clock函数来计算你的机器运行一个循环或者处理其它事件到底花了多少时间:

方法1
#include “stdio.h”
#include “stdlib.h”
#include “time.h”

int main( void )
{
   long    i = 10000000L;
   clock_t start, finish;
   double  duration;
   /*
测量一个事件持续的时间*/
   printf( "Time to do %ld empty loops is ", i );
   start = clock();
   while( i-- )      ;
   finish = clock();
   duration = (double)(finish - start) / CLOCKS_PER_SEC;
   printf( "%f seconds\n", duration );
   system("pause");
}

在笔者的机器上,运行结果如下:
Time to do 10000000 empty loops is 0.03000 seconds

方法2(:摘自付国宏老师的Chart_parser程序)

       struct timeb fStartTime;

       struct timeb fEndTime;

 

       ftime( &fStartTime );

      

       ftime( &fEndTime );

       double dbTotalProcessTime = (float) (((float) (fEndTime.time - fStartTime.time ) +

              ((float) (fEndTime.millitm - fStartTime.millitm) * 0.001 )));


上面我们看到时钟计时单元的长度为1毫秒,那么计时的精度也为1毫秒,那么我们可不可以通过改变CLOCKS_PER_SEC的定义,通过把它定义的大一些,从而使计时精度更高呢?通过尝试,你会发现这样是不行的。在标准C/C++中,最小的计时单位是一毫秒。
三.与日期和时间相关的数据结构
1.    tm
在标准C/C++中,我们可通过tm结构来获得日期和时间,ANSI C标准称使用tm结构的这种时间表示为分解时间(broken-down time)tm结构在time.h中的定义如下:
#ifndef _TM_DEFINED
struct tm {
        int tm_sec;     /*
取值区间为[0,59] */
        int tm_min;     /*
- 取值区间为[0,59] */
        int tm_hour;    /*
- 取值区间为[0,23] */
        int tm_mday;    /*
一个月中的日期 - 取值区间为[1,31] */
        int tm_mon;     /*
月份(从一月开始,0代表一月) - 取值区间为[0,11] */
        int tm_year;    /*
年份,其值等于实际年份减去1900 */
        int tm_wday;    /*
星期取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */
        int tm_yday;    /*
从每年的11开始的天数取值区间为[0,365],其中0代表111代表12,以此类推 */
        int tm_isdst;   /*
夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst0;不了解情况时,tm_isdst()为负。*/
        };
#define _TM_DEFINED
#endif
2.    time_t
日历时间(Calendar Time)是通过time_t数据类型来表示的,用time_t表示的时间(日历时间)是从一个时间点(例如:197011000)到此时的秒数。在time.h中,我们也可以看到time_t是一个长整型数:
#ifndef _TIME_T_DEFINED
typedef long time_t;         /*
时间值 */
#define _TIME_T_DEFINED     /*
避免重复定义 time_t */
#endif

大家可能会产生疑问:既然time_t实际上是长整型,到未来的某一天,从一个时间点(一般是197011000)到那时的秒数(即日历时间)超出了长整形所能表示的数的范围怎么办?对time_t数据类型的值来说,它所表示的时间不能晚于2038118191407。为了能够表示更久远的时间,一些编译器厂商引入了64位甚至更长的整形数来保存日历时间。比如微软在Visual C++中采用了__time64_t数据类型来保存日历时间,并通过_time64()函数来获得日历时间(而不是通过使用32位字的time()函数),这样就可以通过该数据类型保存300111000秒(不包括该时间点)之前的时间。
通过查阅MSDN,我们可以知道Microsoft C/C++ 7.0中时间点的值(time_t对象的值)是从18991231000到该时间点所经过的秒数,而其它各种版本的Microsoft C/C++和所有不同版本的Visual C++都是计算的从197011000秒到该时间点所经过的秒数。
四.与日期和时间相关的函数及应用
4.1
获得日历时间time()

通过time()函数来获得日历时间(Calendar Time),其原型为:
time_t time(time_t * timer);
用法如:

time_t lt;
lt =time(NULL);
printf("The Calendar Time now is %d\n",lt);
output

The Calendar Time now is 1122707619

4.2
获得日期和时间
struct tm * gmtime(const time_t *timer);                                          
struct tm * localtime(const time_t * timer);

gmtime()
是将日历时间转化为世界标准时间(即格林尼治时间),并返回一个tm结构体来保存这个时间。
localtime()
函数是将日历时间转化为本地时间。比如现在用gmtime()函数获得的世界标准时间是200573071820,那么我用localtime()函数在中国地区获得的本地时间会比时间标准时间晚8个小时,即2005730151820。下面是个例子:

#include "time.h"
#include "stdio.h"
int main(void)
{
struct tm *local;
time_t t;
t=time(NULL);
local=localtime(&t);
printf("Local hour is: %d\n",local->tm_hour);
local=gmtime(&t);
printf("UTC hour is: %d\n",local->tm_hour);
return 0;
}

运行结果是:

Local hour is: 15
UTC hour is: 7

4.3
固定的时间格式
我们可以通过asctime()函数和ctime()函数将时间以固定的格式显示出来,两者的返回值都是char*型的字符串。返回的时间格式为:
星期几 月份 日期 :: \n\0
例如:Wed Jan 02 02:03:55 1980\n\0
其中\n是一个换行符,\0是一个空字符,表示字符串结束。下面是两个函数的原型:
char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);

asctime()
函数:    是通过tm结构来生成具有固定格式的保存时间信息的字符串,
ctime
():是通过日历时间来生成时间字符串。只是把tm结构对象中的各个域填到时间字符串的相应位置就行了函数需要先参照本地的时间设置,把日历时间转化为本地时间,然后再生成格式化后的字符串。

在下面,如果lt是一个非空的time_t变量的话,那么:
printf(ctime(lt));
等价于:
struct tm *ptr;
ptr=localtime(lt);
printf(asctime(ptr));


那么,下面这个程序的两条printf语句输出的结果就是不同的了(除非你将本地时区设为世界标准时间所在的时区):
ptr=gmtime(<);
printf(asctime(ptr));
printf(ctime(<));
运行结果:
Sat Jul 30 08:43:03 2005
Sat Jul 30 16:43:03 2005

4.4
自定义时间格式
我们可以使用strftime()函数将时间格式化为我们想要的格式。它的原型如下:
size_t strftime(
   char *strDest,
   size_t maxsize,
   const char *format,
   const struct tm *timeptr
);

我们可以根据format指向字符串中格式命令把timeptr中保存的时间信息放在strDest指向的字符串中,最多向strDest中存放maxsize个字符。该函数返回向strDest指向的字符串中放置的字符数。

函数strftime()的操作有些类似于sprintf():识别以百分号(%)开始的格式命令集合,格式化输出结果放在一个字符串中。格式化命令说明串strDest中各种日期和时间信息的确切表示方法。格式串中的其他字符原样放进串中。格式命令列在下面,它们是区分大小写的。

%a
星期几的简写
%A
星期几的全称
%b
月分的简写
%B
月份的全称
%c
标准的日期的时间串
%C
年份的后两位数字
%d
十进制表示的每月的第几天
%D
//
%e
在两字符域中,十进制表示的每月的第几天
%F
--
%g
年份的后两位数字,使用基于周的年
%G
年分,使用基于周的年
%h
简写的月份名
%H 24
小时制的小时
%I 12
小时制的小时
%j
十进制表示的每年的第几天
%m
十进制表示的月份
%M
十时制表示的分钟数
%n
新行符
%p
本地的AMPM的等价显示
%r 12
小时的时间
%R
显示小时和分钟:hh:mm
%S
十进制的秒数
%t
水平制表符
%T
显示时分秒:hh:mm:ss
%u
每周的第几天,星期一为第一天 (值从06,星期一为0
%U
第年的第几周,把星期日做为第一天(值从053
%V
每年的第几周,使用基于周的年
%w
十进制表示的星期几(值从06,星期天为0
%W
每年的第几周,把星期一做为第一天(值从053
%x
标准的日期串
%X
标准的时间串
%y
不带世纪的十进制年份(值从099
%Y
带世纪部分的十制年份
%z
%Z 时区名称,如果不能得到时区名称则返回空字符。
%%
百分号

如果想显示现在是几点了,并以12小时制显示,就象下面这段程序:
#include “time.h”
#include “stdio.h”
int main(void)
{
struct tm *ptr;
time_t lt;
char str[80];
lt=time(NULL);
ptr=localtime(<);
strftime(str,100,"It is now %I %p",ptr);
printf(str);
return 0;
}

其运行结果为:
It is now 4PM

而下面的程序则显示当前的完整日期:

#include
#include

void main( void )
{
        struct tm *newtime;
        char tmpbuf[128];
        time_t lt1;
        time( <1 );
        newtime=localtime(<1);
        strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", newtime);
        printf(tmpbuf);
}

运行结果:

Today is Saturday, day 30 of July in the year 2005.

4.5
计算持续的时间长度
有时候在实际应用中要计算一个事件持续的时间长度,比如计算打字速度。在第1节计时部分中,我已经用clock函数举了一个例子。Clock()函数可以精确到毫秒级。同时,我们也可以使用difftime()函数,但它只能精确到秒。该函数的定义如下:
double difftime(time_t time1, time_t time0);

虽然该函数返回的以秒计算的时间间隔是double类型的,但这并不说明该时间具有同double一样的精确度,这是由它的参数觉得的(time_t是以秒为单位计算的)。比如下面一段程序:

time_t start,end;
start = time(NULL);
system("pause");
end = time(NULL);
printf("The pause used %f seconds.\n",difftime(end,start));//<-
system("pause");
return 0;
}

运行结果为:
请按任意键继续. . .
The pause used 2.000000 seconds.
请按任意键继续. . .

可以想像,暂停的时间并不那么巧是整整2秒钟。其实,你将上面程序的带有“//<-”注释的一行用下面的一行代码替换:
printf("The pause used %f seconds.\n",end-start);
其运行结果是一样的。
4.6
分解时间转化为日历时间
这里说的分解时间就是以年、月、日、时、分、秒等分量保存的时间结构,在C/C++中是tm结构。我们可以使用mktime()函数将用tm结构表示的时间转化为日历时间。其函数原型如下:

time_t mktime(struct tm * timeptr);
其返回值就是转化后的日历时间。这样我们就可以先制定一个分解时间,然后对这个时间进行操作了,下面的例子可以计算出199771是星期几:
struct tm t;
time_t t_of_day;
t.tm_year=1997-1900;
t.tm_mon=6;
t.tm_mday=1;
t.tm_hour=0;
t.tm_min=0;
t.tm_sec=1;
t.tm_isdst=0;
t_of_day=mktime(&t);
printf(ctime(&t_of_day));
return 0;
}

运行结果:
Tue Jul 01 00:00:01 1997
五.总结
本文介绍了标准C/C++中的有关日期和时间的概念,并通过各种实例讲述了这些函数和数据结构的使用方法。笔者认为,和时间相关的一些概念是相当重要的,理解这些概念是理解各种时间格式的转换的基础,更是应用这些函数和数据结构的基础。

分享到:
评论

相关推荐

    CC++中的和时间 time_t与struct tm转换(pdf)

    CC++中的日期和时间 time_t与struct tm转换CC++中的日期和时间 time_t与struct tm转换

    CC++日期时间time_t与struct_tm转换

    CC++日期时间time_t与struct_tm转换

    time_t数据类型详细介绍及其相关时间操作函数.pdf

    在 `&lt;time.h&gt;` 头文件中定义了一系列与 `time_t` 相关的操作函数,这些函数可以帮助我们进行时间的获取、转换和计算等操作。 1. **`double difftime(time_t time1, time_t time0);`** - 功能:计算两个时间点之间...

    system_data_and_time.rar_C++ Builder time_Get System Time_Time

    2. **将time_t转换为可读的日期和时间(struct tm)**: `localtime()`和`gmtime()`函数用于将`time_t`类型的值转换为结构体`struct tm`,便于格式化输出。`localtime()`返回的是本地时区的时间,而`gmtime()`返回...

    time_t tm timeval 和 时间字符串的转换方法

    在编程中,处理时间是常见的任务之一,而`time_t`、`tm`以及`timeval`是C/C++中处理时间的关键数据类型。本文将详细介绍这些类型以及它们之间的转换方法。 1. 时间存储方式: - `time_t` 类型:这是一个长整数...

    C++时间类 实现日期和秒之间的转换

    在C++编程中,时间处理是一项常见的任务,尤其是在开发涉及日期和时间的系统或应用程序时。C++标准库提供了一些工具来处理日期和时间,但它们可能不是最直观的。本篇文章将深入探讨如何实现一个自定义的时间类,用于...

    c++简单的获取time时间

    首先,`&lt;ctime&gt;`库包含了一系列与时间相关的函数和结构体,如`time_t`类型,`time()`函数以及`struct tm`。`time()`函数返回自1970年1月1日(UTC)以来的秒数,通常称为Unix时间戳。要使用`time()`,我们需要包含`...

    C++ 时间转换与表示

    `mktime()`函数可以将`tm`结构体转换为`time_t`类型的纪元时间: ```c++ time_t convertedTime = mktime(localTime); ``` #### 3.4 计算两个时间点之间的差值 假设我们有两个`time_t`类型的变量`startTime`和`...

    C 代码 给定日期的年、月和日.rar

    2. `struct tm *localtime(const time_t *timer)`:与C++中相同,将时间戳转换为`struct tm`对象。 3. `char *ctime(const time_t *timer)`:将时间戳转换为可读字符串,包括日期和时间。 4. `struct tm *mktime...

    TypeByte@2019_C#_C++_C数据类型转换时间戳转换_

    本项目"TypeByte@2019_C#_C++_C数据类型转换时间戳转换_"显然是针对C#、C++和C这三种编程语言,提供了一种解决方案来实现数据类型的互转以及时间戳的转换。 首先,让我们深入探讨一下C#中的数据类型转换。C#是一门...

    time-function-in-C-and-CPP.rar_In Time

    - `struct tm *gmtime(const time_t *timer)`: 这个函数将`time_t`类型的秒数转换为`struct tm`结构体,表示协调世界时间(UTC)。`struct tm`包含年、月、日、小时、分钟和秒等元素。 - `struct tm *localtime...

    C语言time函数详解

    这个头文件中最重要的数据类型包括`time_t`和`tm`结构体,以及与之相关的函数如`time()`、`difftime()`、`mktime()`、`asctime()`和`strftime()`等。 #### 2. 时间表示:`time_t` `time_t`是一种用于表示时间的...

    Unix time t 和 年月日转换的小工具的源代码 VC6

    源代码的学习价值在于它提供了实际操作的例子,帮助开发者理解如何在C/C++环境中处理时间戳和日期,这对于开发跨平台应用程序或者处理时间相关问题的程序员来说是很有帮助的。通过学习这个工具,你可以加深对Unix...

    time函数标准库(珍藏版)

    - **示例**:创建一个包含特定日期和时间的`tm`结构体,并将其转换为`time_t`类型: ```c struct tm my_time = {0}; my_time.tm_year = 2023 - 1900; // 年份减去1900 my_time.tm_mon = 9 - 1; // 月份减1 my_...

    日期与时间c++.zip

    `ctime()`、`mktime()`、`localtime()`和`gmtime()`等函数用于在`time_t`和`struct tm`之间进行转换。 2. **获取当前时间**: 使用`std::chrono::system_clock`类可以从系统获取当前时间,然后可以将其转换为`time...

    C语言中time函数[参考].pdf

    time.h头文件中定义了许多时间和日期相关的函数和数据类型,例如clock_t、time_t、struct tm等。 7. clock函数 clock函数可以获取当前的时钟计时单元数,返回的结果可以用来计算程序的运行时间。 8. 计时 C/C++...

    C++实现获取本地时间

    - `localtime()`函数:将`time_t`类型的全局时间转换为本地时间结构体`tm`。 - `struct tm`:包含年、月、日、小时、分钟、秒等信息的结构体。 示例代码如下: ```cpp #include int main() { time_t ...

    c++日期与时间.rar

    在C++编程中,处理日期和时间是一项常见的任务。C++标准库提供了`&lt;ctime&gt;`头文件,其中包含了处理日期和时间的相关函数和结构体。本教程将深入探讨如何在C++中进行日期和时间的操作。 首先,让我们了解C++中的基本...

Global site tag (gtag.js) - Google Analytics