Linux时间函数

 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)  命令可用来列出文件的  atime 、 ctime  和  mtime 。
ls -lc filename  列出文件的  ctime
ls -lu filename  列出文件的  atime
ls -l filename  列出文件的  mtime
2. linux 时间函数编程
通过学习许多 C/C++ 库,你可以有很多操作、使用时间的方法。但在这之前你需要了解一些 “ 时间 ” 和 “ 日期 ” 的概念,主要有以下几个:
Coordinated Universal Time ( UTC ):协调世界时,又称为世界标准时间,也就是大家所熟知的格林威治标准时间( Greenwich Mean Time , GMT )。比如,中国内地的时间与 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() 函数获得的世界标准时间是 2005 年 7 月 30 日 7 点 18 分 20 秒 ,那么我用 localtime() 函数在 中国地区获得的本地时间会比世界标准时间晚 8 个小时,即 2005 年 7 月 30 日 15 点 18 分 20 秒 。下面是个例子:

 

#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 结构表示的时间转化为日历时间。其函数原型如下 其返回值就是转化后的日历时间。这样我们就可以先制定一个分解时间,然后对这个时间进行操作了,下面的例子可以计算出 1997 年 7 月 1 日 是星期几:

 

#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() 函数,是不是我们可以操作现在之前的任何时间呢?你可以通过这种办法算出 1945 年 8 月 15 号是星期几吗?答案是否定的。因为这个时间在 1970 年 1 月 1 日 之前,所以在大多数编译器中,这样的程序虽然可以编译通过,但运行时会异常终止。
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  本地的 AM 或 PM 的等价显示  
%r 12 小时的时间  
%R  显示小时和分钟: hh:mm 
%S  十进制的秒数  
%t  水平制表符  
%T  显示时分秒: hh:mm:ss 
%u  每周的第几天,星期一为第一天 (值从 0 到 6 ,星期一为 0 )  
%U  第年的第几周,把星期日做为第一天(值从 0 到 53 )  
%V  每年的第几周,使用基于周的年  
%w  十进制表示的星期几(值从 0 到 6 ,星期天为 0 )  
%W  每年的第几周,把星期一做为第一天(值从 0 到 53 )  
%x  标准的日期串  
%X  标准的时间串  
%y  不带世纪的十进制年份(值从 0 到 99 )  
%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); 
 
其运行结果是一样的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值