【转载】Linux时间相关结构与函数
1 时间的获取
在程序当中, 我们经常要输出系统当前的时间,比如日志文件中的每一个事件都要记录其产生时间。在 C 语言中获取当前时间的方法有以下几种,它们所获得的时间精度从秒级到纳秒,各有所不同。
表 1. C 时间函数
function 定义 | 含义 | 返回值 | 精度 |
---|---|---|---|
time() | time 函数获得从 1970 年 1 月 1 日 0 点到当前的秒数,存储在time_t结构之中。 |
|
秒 |
gettimeofday() | gettimeofday 函数返回从 1970 年 1 月 1 日 0 点以来,到现在的时间。用 timeval 数据结构表示。 | struct timeval { time_t tv_sec; long int tv_usec; }; |
微秒 |
clock_gettime() | clock_gettime 函数返回从 1970 年 1 月 1 日 0 点以来,到现在的时间。用 timespec 数据结构表示。 支持不广泛。属于实时扩展。 |
struct timespec { time_t tv_sec; long int tv_nsec; }; |
纳秒 |
ftime() | 函数返回从 1970 年 1 月 1 日 0 点以来,到现在的时间。用timeb 数据结构表示。已经过时, 被 time() 替代。尽量不使用。 |
struct timeb { time_t time; unsigned short
|
毫秒 |
GUN/Linux 提供了三个标准的 API 用来获取当前时间,time()/gettimeofday()/clock_gettime(),它们的区别仅在于获取的时间精度不同,您可以根据需要 选取合适的调用。ftime() 是老的一些系统中的时间调用,很多 Linux 版本虽然支持它,但仅仅是为了向前兼容性,新开发的软件不建议使用 ftime() 来获得当前时间。
2 时间显示和转换
目前我们得到的时间是一个数字,无论精度如 何,它代表的仅是一个差值。比如精度为秒的 time() 函数,返回一个 time_t 类型的整数。假设当前时间为 2011 年 12 月 7 日下午 20 点 29 分 51 秒,那么 time_t 的值为:1323318591。即距离 1970 年 1 月 1 日零点,我们已经过去了 1323318591 秒。(这里的 1970 年 1 月 1 日零点是格林威治时间,而不是北京时间。)我们下面讨论的时间如果不特别说明都是格林威治时间,也叫 GMT 时间,或者 UTC 时间。
字符串“1323318591 秒”对于多数人都没有太大的意义,我们更愿意看到“2011 年 12 月 7 日”这样的显示。因此当我们得到秒,毫秒,甚至纳秒表示的当前时间之后,往往需要将这些数字转换为人们所熟悉的时间表示方法。
由 于国家,习惯和时区的不同,时间的表示方法并没有一个统一的格式。为了满足各种时间显示的需求,标准 C 库提供了许多时间格式转换的函数。这些函数的数量众多,容易让人迷惑,记住它们的用法十分不易。在这里我借用 Michael Kerrisk 在《Linux Programming Interface》一书中的插图,来对这些标准 C 函数进行一个总体的概览。
图 1. 各种时间显示格式转换函数关系图
从上图可以看到,time()/gettimeofday() 从内核得到当前时间之后,该当前时间值可以被两大类函数转换为更加容易阅读的显示格式:
- 固定格式转换
- 用户指定格式转换函数。
固定格式转换
用 ctime() 函数转换出来的时间格式是系统固定的,调用者无法改动,因此被称为固定格式转换。如果您对日期格式没有特殊的要求,那么用它基本上就可以了,简单,不用记忆很多的参数。
用户指定格式转换
典型的 ctime() 格式如下:
Wed Dec 7 20:45:43 PST 2011
有些人觉得这个格式太长,类似 Wed,星期三这样的信息很多情况下都没有啥用途。人们可能更喜欢其他格式:比如2011-12-07 20:45。在这种情况下,就需要进行时间显示格式转换。做法为:先把从内核得到的时间值转换为 struct tm 类型的值,然后调用 strftime() 等函数来输出自定义的时间格式字符串。
下面我列举一些实例,以便读者更清晰地理解众多的时间转换函数的用法。
3 各标准 C 时间转换函数的解释和举例
char *ctime(const time_t *clock);
使用函数 ctime 将秒数转化为字符串. 这个函数的返回类型是固定的:一个可能值为”Thu Dec 7 14:58:59 2000”。这个字符串的长度和显示格式是固定的。
清单 1,time 的使用
1 #include <time.h>
2 int main ()
3 {
4 time_t time_raw_format;
5 time ( &time_raw_format ); //获取当前时间
6 printf (" time is [%d]\n", time_raw_format);
7 //用 ctime 将时间转换为字符串输出
8 printf ( "The current local time: %s", ctime(&time_raw_format));
9 return ;
}
自定义格式转换
为了更灵活的显示,需要把类型 time_t 转换为 tm 数据结构。tm 数据结构将时间分别保存到代表年,月,日,时,分,秒等不同的变量中。不再是一个令人费解的 64 位整数了。这种数据结构是各种自定义格式转换函数所需要的输入形式。
清单 2,数据结构 tm
1 struct tm {
2 int tm_sec; /* Seconds (0-60) */
3 int tm_min; /* Minutes (0-59) */
4 int tm_hour; /* Hours (0-23) */
5 int tm_mday; /* Day of the month (1-31) */
6 int tm_mon; /* Month (0-11) */
7 int tm_year; /* Year since 1900 */
8 int tm_wday; /* Day of the week (Sunday = 0)*/
9 int tm_yday; /* Day in the year (0-365; 1 Jan = 0)*/
int tm_isdst; /* Daylight saving time flag
> 0: DST is in effect;
= 0: DST is not effect;
< 0: DST information not available */
};
可以使用 gmtime() 和 localtime() 把 time_t 转换为 tm 数据格式,其中 gmtime() 把时间转换为格林威治时间;localtime 则转换为当地时间。
清单 3,时间转换函数定义
#include <time.h>
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
使用 tm 来表示时间,您就可以调用 asctime() 和 strftime() 将时间转换为字符串了。asctime() 的输出格式固定,和 ctime() 相同。strftime() 则类似我们最熟悉的 printf() 函数,您可以通过输入参数自定义时间的输出格式。
size_t strftime(char *outstr, size_t maxsize, const char *format,const struct tm *timeptr);
清单 4,时间显示转换
int main ()
{
time_t time_raw_format;
struct tm * time_struct;
char buf [];
time ( &time_raw_format );
time_struct = localtime ( &time_raw_format );
strftime (buf,,"It is now: %I:%M%p.",time_struct);
puts (buf);
return ;
}
该例子程序的输出结果如下:
It is now: 02:45PM.
从以上的例子可以看到,利用从 time() 得到的时间值,可以调用各种转换函数将其转换成更方便人们阅读的形式。
此 外从前面的总结中我们也了解到,还有两个 C 函数可以获得当前时间,gettimeofday() 以及 clock_gettime(),它们分别返回 struct timeval 或者 timespec 代表的高精度的时间值。在目前的 GLibC 中,还没有直接把 struct timeval/timespec 转换为 struct tm 的函数。一般的做法是将 timeval 中的 tv_sec 转换为 tm,使用上面所述的方法转换为字符串,最后在显示的时候追加上 tv_usec,比如下面的例子代码:
清单 5,更多时间显示转换
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[], buf[];
gettimeofday(&tv, NULL); //获取当前时间到 tv
nowtime = tv.tv_sec; //nowtime 存储了秒级的时间值
nowtm = localtime(&nowtime); //转换为 tm 数据结构
//用 strftime 函数将 tv 转换为字符串,但 strftime 函数只能达到秒级精度
strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
//将毫秒值追加到 strftime 转换的字符串末尾
snprintf(buf, sizeof buf, "%s.%06d", tmbuf, tv.tv_usec);
【转载】Linux时间相关结构与函数的更多相关文章
- CentOS6.5菜鸟之旅:纯转载Linux目录结构
来自:http://www.iteye.com/topic/1125162 使用linux也有一年多时间了 最近也是一直在维护网站系统主机 下面是linux目录结构说明 本人使用的是centos系 ...
- Linux目录结构及常用命令(转载)
一.Linux目录结构 你想知道为什么某些程序位于/bin下,或者/sbin,或者/usr/bin,或/usr/sbin目录下吗?例如,less命令位于/usr/bin目录下.为什么没在/bin中,或 ...
- 每天一个linux命令(目录文件操作):【转载】Linux 目录结构
对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统至关重要,下面 ...
- Linux下利用ioctl函数获取网卡信息
linux下的ioctl函数原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv ...
- Linux下系统时间函数、DST等相关问题总结(转)
Linux下系统时间函数.DST等相关问题总结 下面这个结构体存储了跟时区相关的位移量(offset)以及是否存在DST等信息,根据所在的时区信息,很容易找到系统时间与UTC时间之间的时区偏移,另外根 ...
- [转载]Linux进程调度原理
[转载]Linux进程调度原理 Linux进程调度原理 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交 ...
- [转]【Linux】Linux 目录结构
初学Linux,首先需要弄清Linux 标准目录结构 / root --- 启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home --- 存储普通用户的个人文件 ftp ...
- Linux实战教学笔记07:Linux系统目录结构介绍
第七节 Linux系统目录结构介绍 标签(空格分隔):Linux实战教学笔记 第1章 前言 windows目录结构 C:\windows D:\Program Files E:\你懂的\精品 F:\你 ...
- Linux系统目录结构以及简单说明
Linux系统目录结构以及简单说明 linux目录图: / root --- 启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home --- 存储普通用户的个人文件 ftp ...
随机推荐
- 【转】qlv文件如何转换成mp4 怎样把下载好的qlv格式视频转换成MP4格式
狸窝 复制 收藏 保存到桌面 快速找教程方案 反馈需求 社会主义核心价值观 客服QQ41442901 马上注册 升级VIP 对于视频文件之间的转换问题,我也已经是无力吐槽了,每个 ...
- uImage和zImage的区别
1.各种文件的意义 vmlinux 编译出来的最原始的内核文件,未压缩. zImage 是vmlinux经过gzip压缩后的文件. bzImage bz表示“big zImage”,不是用bzi ...
- Java与算法之(3) - 斐波那契数列
斐波那契数列问题:如果一对兔子每月能生1对小兔子,而每对小兔在它出生后的第三个月里,又能开始生1对小兔子,假定在不发生死亡的情况下,由一对初生的兔子开始,1年后能繁殖出多少对兔子? 首先手工计算来总结 ...
- [51nod1254]最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 利用Selenium+PhantomJS 实现截图
using OpenQA.Selenium; using OpenQA.Selenium.PhantomJS; using System; using System.Drawing; using Sy ...
- [UWP]使用Reveal
1. 前言 之前在 如何使用Fluent Design System 这篇文章里已经简单介绍过Reveal的用法,这篇再详细介绍其它内容. 2. 自定义RevealButtonStyle 我觉得常用I ...
- Android开发——BroadcastReceiver广播的使用
想要了解广播定义及相关原理的可以看下这一篇BroadcastReceiver史上最全面解析 简单地对广播进行分类吧,广播有两个角色,一个是广播发送者,另外一个是广播接收者 广播按照类型分为两种,一种是 ...
- Spark算子--mapPartitions和mapPartitionsWithIndex
mapPartitions--Transformation类算子 代码示例 result mapPartitionsWithIndex--Transformation类算子 代码示例 result ...
- dede list列表页和文章页分别使用if else
标签: dede 2015-01-25 19:33 755人阅读 评论(0) 收藏 举报 分类: [ Dede ](20) 版权声明:本文为博主原创文章,未经博主允许不得转载. list列表页中使用i ...
- 如何跳出页面的Frame框架
摘录自:http://blog.csdn.net/clare504/article/details/9347363 很多网页都是框架结构的,在很多的情况下会通过按钮点击事件或链接,跳出框架转到其它界面 ...