【原创】C语言时间函数简介

  1. 云栖社区>
  2. 博客列表>
  3. 正文

【原创】C语言时间函数简介

摩云飞 2016-05-11 14:16:17 浏览729 评论0

摘要: 以下内容参考自 这里 。 ====== 【C 库与 C++ 库的关系】 The C++ library includes the same definitions as the C language library organized in the same structure of header files, with the following differences: a.

以下内容参考自 这里  

====== 

C 库与 C++ 库的关系 
The C++ library includes the same definitions as the C language library organized in the same structure of header files, with the following differences: 
a. Each header file has the same name as the C language version but with a "c" prefix and no extension. For example, the C++ equivalent for the C language header file <stdlib.h> is <cstdlib>. 
b. Every element of the library is defined within the std namespace. 

C 标准与 C++ 标准之间的关系 
C++98 includes the C library as described by the 1990 ISO C standard and its amendment #1 (ISO/IEC 9899:1990 and ISO/IEC 9899:1990/DAM 1). 

C++11 includes the C library as described by the 1999 ISO C standard and its Technical Corrigenda 1, 2 and 3 (ISO/IEC 9899:1999 and ISO/IEC 9899:1999/Cor.1,2,3), plus <cuchar> (as by ISO/IEC 19769:2004). 

Other introductions by the 2011 ISO C standard are not compatible with C++. 

====== 

以下内容在头文件 <ctime> (time.h) 中定义。 

time_t】 -- Time type 
Alias of a fundamental arithmetic type capable of representing times, as those returned by function time. 
用于表示时间值的基础数字类型的别名,例如作为 time() 的返回值。 

For historical reasons, it is generally implemented as an integral value representing the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC (i.e., a unix timestamp). Although libraries may implement this type using alternative time representations. 
由于历史原因,通常该值被实现为从 00:00 hours, Jan 1, 1970 UTC (i.e., the current unix timestamp开始所经历以整型表示的秒数值。然而,有些库可能将该类型实现为其他种类的时间表示形式。 

Portable programs should not use values of this type directly, but always rely on calls to elements of the standard library to translate them to portable types(such as localtime, gmtime or difftime). 
编写可移植性的程序时,不应该直接使用这种类型的值,而应总是通过调用标准库中的其他函数将其转换为可移植的类型(例如使用 localtime、gmtime 或 difftime)。 


struct tm】 -- Time structure 
Structure containing a calendar date and time broken down into its components. 
将当前日历时间值(从1970年1月1日00:00开始的秒数)按 year、mon、day、hour、min 和 sec 保存在该结构中。 

The structure contains nine members of type int (in any order), which are: 
Member 
Type 
Meaning 
Range 
tm_sec 
int 
seconds after the minute
0-61* 
tm_min 
int 
minutes after the hour
0-59
tm_hour 
int 
hours since midnight
0-23 
tm_mday 
int 
day of the month
1-31 
tm_mon 
int 
months since January
0-11 
tm_year 
int 
years since 1900( 这个值需要注意下 

tm_wday 
int 
days since Sunday
0-6 
tm_yday 
int 
days since January 1  
0-365
tm_isdst 
int 
Daylight Saving Time flag



time() 

原型 
time_t time (time_t* timer); 
功能 
Get current time (获取当前时间

Get the current calendar time as a value of type time_t. 
获取当前日历时间值(从1970年1月1日00:00开始的秒数)作为 time_t 的值。 

Data races 
The object pointed by timer is modified (if not null). 


localtime() 

原型 
struct tm * localtime (const time_t * timer); 
功能 
Convert time_t to tm as local time(转换为本地时区时间 

Uses the value pointed by timer to fill a tm structure with the values that represent the corresponding time, expressed for the local timezone. 
将 time_t 类型的时间值进行转换,填入 tm 结构中,以本地时区时间的形式进行表达。 

The returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime. 
其返回值指向了一个内部对象,所以后续调用 gmtime 或者 localtime 将改变其值。 

Data races 
The function accesses the object pointed by timer. 
The function also accesses and modifies a shared internal object, which may introduce data races on concurrent calls to gmtime and localtime. Some libraries provide an alternative function that avoids this data race: localtime_r (non-portable). 


gmtime() 

原型 
struct tm * gmtime (const time_t * timer); 
功能 
Convert time_t to tm as UTC time(转换为 GMT 时区时间 

Uses the value pointed by timer to fill a tm structure with the values that represent the corresponding time, expressed as a UTC time (i.e., the time at the GMT timezone). 
将 time_t 类型的时间值进行转换,填入 tm 结构中,以 GMT 时区时间的形式进行表达。 

The returned value points to an internal object whose validity or value may be altered by any subsequent call to gmtime or localtime. 

Data races 
The function accesses the object pointed by timer. 
The function also accesses and modifies a shared internal object, which may introduce data races on concurrent calls to gmtime and localtime. Some libraries provide an alternative function that avoids this data race: gmtime_r (non-portable). 


ctime() 

原型 
char* ctime (const time_t * timer); 
功能 
Convert time_t value to string 将 time_t 对应的数字时间值转换成时间字符串

Interprets the value pointed by timer as a calendar time and converts it to a C-string containing a human-readable version of the corresponding time and date, in terms of local time. 
将 time_t 类型的时间值转换为 C-string 类型的值,包含人类可读的、本地时区的、时间表达形式。 

The returned string has the following format: 
Www Mmm dd hh:mm:ss yyyy 

Where Www is the weekday, Mmm the month (in letters), dd the day of the month, hh:mm:ss the time, and yyyy the year. 

The string is followed by a new-line character ('\n') and terminated with a null-character. 
生成的字符串最后包含换行符 '\n' 和字符串结束符 '\0' (这个可能会影响打印输出的排版)。 

This function is equivalent to:  
该函数与下面的函数具有等价的功能:  

asctime ( localtime (timer)) 

For an alternative with custom date formatting, see strftime. 
若想对输出结果进行自定义控制,请使用 strftime 。 

The returned value points to an internal array whose validity or value may be altered by any subsequent call to asctime or ctime. 
该函数的返回值指向了一个内部字符数组,所以后续调用 asctime 或者 ctime 将改变其内部的值。 

Data races 
The function accesses the object pointed by timer. 
The function also accesses and modifies a shared internal buffer, which may cause data races on concurrent calls to asctime or ctime. Some libraries provide an alternative function that avoids this data race: ctime_r (non-portable). 


asctime() 

原型 
char* asctime (const struct tm * timeptr); 
功能 
Convert tm structure to string 转换 tm 结构中的内容成时间字符串

Interprets the contents of the tm structure pointed by timeptr as a calendar time and converts it to a C-string containing a human-readable version of the corresponding date and time. 
解析 tm 结构中的内容,并将其转换成人类可读的、C 字符串形式的日期和时间。

The returned string has the following format: 
Www Mmm dd hh:mm:ss yyyy 

Where Www is the weekday, Mmm the month (in letters), dd the day of the month, hh:mm:ss the time, and yyyy the year. 

The string is followed by a new-line character ('\n') and terminated with a null-character. 

For an alternative with custom date formatting, see strftime. 
若想对输出结果进行自定义控制,请使用 strftime 。 

The returned value points to an internal array whose validity or value may be altered by any subsequent call to asctime or ctime. 
该函数的返回值指向了一个内部字符数组,所以后续调用 asctime 或者 ctime 将改变其内部的值。 

Data races 
The function accesses the object pointed by timeptr. 
The function also accesses and modifies a shared internal buffer, which may cause data races on concurrent calls to asctime or ctime. Some libraries provide an alternative function that avoids this data race: asctime_r (non-portable). 


strftime() 

原型 
size_t strftime (char* ptr, size_t maxsize, const char* format, const struct tm* timeptr ); 
功能 
Format time as string 将 tm 结构中保存的时间值格式化成指定形式的字符串

Copies into ptr the content of format, expanding its format specifiers into the corresponding values that represent the time described in timeptr, with a limit of maxsize characters. 
将由 tm 结构体指定的时间值,以格式 format 写入由 ptr 指定的 buffer 中,限定最大长度为 maxsize 。 

ptr -- Pointer to the destination array where the resulting C string is copied. 
maxsize -- Maximum number of characters to be copied to ptr, including the terminating null-character. 
format -- C string containing any combination of regular characters and special format specifiers. These format specifiers are replaced by the function to the corresponding values to represent the time specified in timeptr. They all begin with a percentage (%) sign, and are: 
... 
timeptr -- Pointer to a tm structure that contains a calendar time broken down into its components (see struct tm). 

Return Value 返回值 
If the length of the resulting C string, including the terminating null-character, doesn't exceed maxsize, the function returns the total number of characters copied to ptr (not including the terminating null-character). 
Otherwise, it returns zero, and the contents of the array pointed by ptr are indeterminate. 
如果最终产生的 C string 的长度,算上字符串结束符,仍然没有超过 maxsize 的值,那么该函数将返回实际拷贝到 ptr 所指向 buffer 的字符总数(不算字符串结束符)。否则,该函数返回 0 ,并且此时由 ptr 指向的 buffer 中的内容是不确定的。 

Compatibility 兼容性问题 
Particular library implementations may support additional specifiers or combinations. 
Those listed here are supported by the latest C and C++ standards (both published in 2011), but those in yellow were introduced in C99 (only required for C++ implementations since C++11), and may not be supported by libraries that comply with older standards. 

Data races 
The function accesses the array pointed by format and the object pointed by timeptr. On success, it also modifies the elements in the array pointed by ptr. 
Concurrently changing locale settings may also introduce data races. 

该函数可以对输出格式做自定义控制,需要注意的是,有些控制存在兼容性问题。 

====== 

经常能看到如下两种提供时间戳的代码段: 

1. 使用 gettimeofday() 提供精度到毫秒的时间戳(可以到微秒级别)
1
2
3
4
5
6
7
8
{
    struct timeval tv;
 
    gettimeofday(&tv,NULL);
    off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
    snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
    fprintf(fp,"[%d] %s %c %s\n",(int)getpid(),buf,c[level],msg);
}

2. 使用 time()提供精度到秒的时间戳

1
2
3
4
5
6
7
{
    time_t t;
    t = time( NULL );
    local = localtime( &t );
    timestr = asctime( local );
    fprintf( stderr, "%s\n", timestr );
}

这两种有多大区别呢?网上找到如下的说明:

 times, time, gettimeofday 和clock这四个函数有什么区别 

这些函数分别用于不同用处:有些相互有点关系,有些则完全没有关系,所以没法比较所谓的优缺点。具体每个函数的用法,可以 man xxx 或者在网上搜,这里只给简单的说明: 
  • times() 用来统计进程及其子进程执行所消耗的 CPU 时间。常见用法是在不同地方调用两次这个函数,从而可以计算出进程或子进程在这两次调用之间消耗了多少 CPU 时间。
  • time() 返回当前相对于 Epoch (在 linux/unix 里,这个时间一般指 1970 年 1 月 1 日 0 点 0 分 0 秒)所经过的秒数。 常见用法是在不同地方调用两次这个函数,从而可以计算这两处调用之间系统时间过了多少秒。
  • gettimeofday() 有点类似于 time(),获取当前相对于 Epoch 所经过的秒数+微秒数
  • clock() 返回当前进程消耗的 CPU 时间,用法类似于 times(),函数返回值是否包含等待子进程的时间,在不同的实现中是不一样的,在 linux 里不包含。 
      由上可见, times() 和 clock() 可以算成一类,用来计算 CPU 时间; time() 和 gettimeofday() 可以算成一类,都是用来计算真实时间的。


 time 和 gettimeofday 的性能差异  

      两个都是 glibc 中实现的获取时间的函数,gettimeofday() 支持获取微秒级别的时间精度,time() 支持获取秒级时间精度,两者在性能上有差别吗? 
      其实,基本上没有多少性能差别,因为 time() 其实就是把 gettimeofday() 包装了一层。但是测试过程中发现 time() 比 gettimeofday() 性能好了一点点, 可能是 time() 函数的接口形式简单吧,堆栈处理快的缘故。 

如下是 glibc-2.18 中 time() 函数的实现,代码取自 glibc-2.18/sysdeps/posix/time.c 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stddef.h>       /* For NULL.  */
#include <time.h>
#include <sys/time.h>
 
 
/* Return the current time as a `time_t' and also put it in *T if T is
   not NULL.  Time is represented as seconds from Jan 1 00:00:00 1970.  */
time_t
time (t)
     time_t *t;
{
  struct timeval tv;
  time_t result;
 
  if (__gettimeofday (&tv, (struct timezone *) NULL))
    result = (time_t) -1;
  else
    result = (time_t) tv.tv_sec;
 
  if (t != NULL)
    *t = result;
  return result;
}
       由上面可知,如果你的时间戳不要求达到毫秒级别,那么其实不需要使用 gettimeofday();否则一旦使用,就需要处理 windows() 平台上的移植问题。

用云栖社区APP,舒服~

【云栖快讯】诚邀你用自己的技术能力来用心回答每一个问题,通过回答传承技术知识、经验、心得,问答专家期待你加入!  详情请点击

网友评论