Linux时间函数

来源:互联网 发布:用户画像数据分析工具 编辑:程序博客网 时间:2024/04/29 13:14

 1. linux文件的时间

linux文件的时间分为三种,访问时间(access time)修改时间(modify time)和创造时间(create time)。其中:
文件的 Access time,atime 是在读取文件或者执行文件时更改的。
文件的 Modified time,mtime 是在写入文件时随文件内容的更改而更改的
文件的 Create time,ctime 是在写入文件、更改所有者、权限或链接设置时随Inode 的内容更改而更改的。
因此,更改文件的内容即会更改 mtime  ctime,但是文件的 ctime 可能会在 mtime 未发生任何变化时更改 - 在权限更改,但是文件内容没有变化的情况下。
ls(1) 命令可用来列出文件的 atimectime  mtime
ls -lc filename 列出文件的 ctime
ls -lu filename 列出文件的 atime
ls -l filename 列出文件的 mtime
2. linux 时间函数编程
通过学习许多C/C++库,你可以有很多操作、使用时间的方法。但在这之前你需要了解一些时间日期的概念,主要有以下几个:
Coordinated Universal TimeUTC):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间(Greenwich Mean TimeGMT)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5 
Calendar Time:日历时间,是用从一个标准时间点到此时的时间经过的秒数来表示的时间。这个标准时间点对不同的编译器来说会有所不同,但对一个编译系统来说,这个标准时间点是不变的,该编译系统中的时间对应的日历时间都通过该标准时间点来衡量,所以可以说日历时间是相对时间,但是无论你在哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。 
epoch:时间点。时间点在标准C/C++中是一个整数,它用此时的时间和标准时间点相差的秒数(即日历时间)来表示。 
clock tick:时钟计时单元(而不把它叫做时钟滴答次数),一个时钟计时单元的时间长短是由CPU控制的。一个clock tick不是CPU的一个时钟周期,而是C/C++的一个基本计时单位。
2.1 相关函数和结构

 

#include <time.h>
char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
time_t mktime(struct tm *tm);
 
struct timeval { 
     int tv_sec; 
     int tv_usec; 
}; 
其中tv_sec是由凌晨开始算起的秒数,tv_usec则是微秒(10E-6 second)。 
 
struct timezone { 
     int tv_minuteswest; 
     int tv_dsttime; 
}; 
tv_minuteswest是格林威治时间往西方的时差,tv_dsttime则是时间的修正方式。 
 
struct timespec 
     long int tv_sec; 
     long int tv_nsec; 
}; 
tv_nsec是nano second(10E-9 second)。 
 
struct tm 
     int tm_sec; 
     int tm_min; 
     int tm_hour; 
     int tm_mday; 
     int tm_mon; 
     int tm_year; 
     int tm_wday; 
     int tm_yday; 
     int tm_isdst; 
}; 
tm_sec表「秒」数,在[0,61]之间,多出来的两秒是用来处理跳秒问题用的。 
tm_min表「分」数,在[0,59]之间。 
tm_hour表「时」数,在[0,23]之间。 
tm_mday表「本月第几日」,在[1,31]之间。 
tm_mon表「本年第几月」,在[0,11]之间。 
tm_year要加1900表示那一年。 
tm_wday表「本第几日」,在[0,6]之间。 
tm_yday表「本年第几日」,在[0,365]之间,闰年有366日。 
tm_isdst表是否为「日光节约时间」。 
 
struct   itimerval {
   struct   timeval it_interval;
   struct   timeval it_value;
};
it_interval成员表示间隔计数器的初始值,而it_value成员表示间隔计数器的当前值。#ifndef _TIME_T_DEFINED 
typedef long time_t; /* 时间值 */ 
#define _TIME_T_DEFINED /* 避免重复定义 time_t */ 
#endif

 

其中time()函数来获得日历时间(Calendar Time)。
gmtime()
localtime(),用于获取日历时间,也就是我们平时所说的年、月、日、时、分、秒等信息,这些信息保存在一个名为tm的结构体中。其中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

 

 asctime()函数和ctime()函数将时间以固定的格式显示出来,两者的返回值都是char*型的字符串。返回的时间格式为:
星期几月份日期::/n/0 
例如:Wed Jan 02 02:03:55 1980/n/0
其中/n是一个换行符,/0是一个空字符,表示字符串结束。其asctime()函数是通过tm结构来生成具有固定格式的保存时间信息的字符串,而ctime()是通过日历时间来生成时间字符串。这样的话,asctime()函数只是把tm结构对象中的各个域填到时间字符串的相应位置就行了,而ctime()函数需要先参照本地的时间设置,把日历时间转化为本地时间,然后再生成格式化后的字符串。在下面,如果t是一个非空的time_t变量的话,那么:printf(ctime(&t));等价于:
struct tm *ptr; 
ptr=localtime(&t); 
printf(asctime(ptr));
那么,下面这个程序的两条printf语句输出的结果就是不同的了(除非你将本地时区设为世界标准时间所在的时区):

 

#include <time.h> 
#include "stdio.h" 
int main(void) 
struct tm *ptr; 
time_t lt; 
lt =time(NULL); 
ptr=gmtime(<); 
printf(asctime(ptr)); 
printf(ctime(<)); 
return 0; 
 
运行结果:Sat Jul 30 08:43:03 2005 
Sat Jul 30 16:43:03 2005 

 

mktime()函数将用tm结构表示的时间转化为日历时间。其函数原型如下其返回值就是转化后的日历时间。这样我们就可以先制定一个分解时间,然后对这个时间进行操作了,下面的例子可以计算出199771是星期几:

 

#include <time.h> 
#include "stdio.h" 
#include "stdlib.h" 
int main(void) 
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 

 

 现在注意了,有了mktime()函数,是不是我们可以操作现在之前的任何时间呢?你可以通过这种办法算出1945815号是星期几吗?答案是否定的。因为这个时间在197011之前,所以在大多数编译器中,这样的程序虽然可以编译通过,但运行时会异常终止。
2.2自定义时间格式
我们可以使用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 <stdio.h> 
#include <time.h> 
 
void main( void ) 
struct tm *newtime; 
char tmpbuf[128]; 
time_t lt1; 
time( &lt1 ); 
newtime=localtime(&lt1); 
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.

 

 
2.3 计算持续时间的长度 
有时候在实际应用中要计算一个事件持续的时间长度,比如计算打字速度。在第1节计时部分中,我已经用clock函数举了一个例子。Clock()函数可以精确到毫秒级。同时,我们也可以使用difftime()函数,但它只能精确到秒。该函数的定义如下:
double difftime(time_t time1, time_t time0);
虽然该函数返回的以秒计算的时间间隔是double类型的,但这并不说明该时间具有同double一样的精确度,这是由它的参数觉得的(time_t是以秒为单位计算的)。比如下面一段程序:

 

#include <time.h> 
#include "stdio.h" 
#include "stdlib.h" 
int main(void) 
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); 
 
其运行结果是一样的。
原创粉丝点击