《3.linux应用编程和网络编程-第3部分-3.3.获取系统信息》-3.3.1.关于时间的概念 - 3.3.2.linux系统中的时间 -3.3.3.时间相关API实战1

《3.linux应用编程和网络编程-第3部分-3.3.获取系统信息》

 

第一部分、章节目录
3.3.1.关于时间的概念
3.3.2.linux系统中的时间
3.3.3.时间相关API实战1
3.3.4.时间相关API实战2
3.3.5.linux中使用随机数  
3.3.6.proc文件系统介绍   驱动调试有关,代码调试
3.3.7.proc文件系统的使用



3.3.1.关于时间的概念
    本节讲述有关时间的一些概念,包括GMT时间、UTC时间和计算机中与时间有关的部件、工作原理。
第三部分、随堂记录
3.3.1.关于时间的概念
3.3.1.1、GMT时间
(1)GMT是格林尼治时间,也就是格林尼治地区的当地之间。
(2)GMT时间的意义?

用格林尼治的当地时间作为全球国际时间,用以描述全球性的事件的时间,方便大家记忆。
(3)一般为了方便,一个国家都统一使用一个当地时间。

3.3.1.2、UTC时间
(1)GMT时间是以前使用的,近些年来越来越多的使用UTC时间。
(2)关于北京时间,可以参考:http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html

 3.3.1.3、计算机中与时间有关的部件
(1)点时间和段时间。

点时间:时间点 精确到 秒

段时间: 3分钟、   段时间=点时间 - 点时间


(2)定时器和实时时钟。(内部外设)

定时器(timer)定的时间就是段时间

实时时钟(RTC)就是和点时间有关的一个器件。

3.3.2.linux系统中的时间
3.3.2.1、jiffies的引入
(1) jiffies是linux内核中的一个全局变量这个变量用来记录以内核的节拍时间为单位时间长度的一个数值。
(2)内核配置的时候定义了一个节拍时间,实际上linux内核的调度系统作时就是以这个节拍时间为时间片的。
(3jiffies变量开机时有一个基准值,然后内核每过一个节拍时间jiffies就会加1,然后到了系统的任意一个时间我们当前时间就被jiffies这个变量所标注。
 

3.3.2.2、linux系统如何记录时间
(1)内核在开机启动的时候会读取RTC硬件获取一个时间作为初始基准时间这个基准时间对应一个jiffies值(这个基准时间换算成jiffies值的方法是:用这个时间减去1970-01-01 00:00:00 +0000(UTC),然后把这个时间段换算成jiffies数值),这个jiffies值作为我们开机时的基准jiffies值存在。然后系统运行时每个时钟节拍的末尾都会给jiffies这个全局变量加1,因此操作系统就使用jiffies这个全局变量记录了下来当前的时间。当我们需要当前时间点时,就用jiffies这个时间点去计算(计算方法就是先把这个jiffies值对应的时间段算出来,然后加上1970-01-01 00:00:00 +0000(UTC)即可得到这个时间点)


(2)其实操作系统只在开机时读一次RTC,整个系统运行过程中RTC是无作用的RTC的真正作用其实是在OS的2次开机之间进行时间的保存
(3)理解时一定要点时间段时间结合起来理解。jiffies这个变量记录的其实是段时间(其实就是当前时间和1970-01-01 00:00:00 +0000(UTC)这个时间的差值)
(4)一个时间节拍的时间取决于操作系统的配置,现代linux系统一般是10ms或者1ms这个时间其实就是调度时间,在内核中用HZ来记录和表示。如果HZ定义成1000 那么时钟节拍就是1/HZ,也就是1ms。这些在学习驱动时会用到。

3.3.2.3、linux中时间相关的系统调用
(1)常用的时间相关的API和C库函数有9个:time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/settimeofday有9个:time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/settimeofday


(2)time系统调用返回当前时间以秒为单位的距离1970-01-01 00:00:00 +0000(UTC)过去的秒数。这个time内部就是用jiffies换算得到的秒数。其他函数基本都是围绕着time来工作的。

 


(3)gmtime和localtime会把time得到的秒数变成一个struct tm结构体表示的时间。区别是gmtime得到的是国际时间,而localtime得到的是本地(指的是你运行localtime函数的程序所在的计算机所设置的时区对应的本地时间)时间。mktime用来完成相反方向的转换(struct tm到time_t)


(4)如果从struct tm出发想得到字符串格式的时间,可以用asctime或者strftime都可以。(如果从time_t出发想得到字符串格式的时间用ctime即可


(5) gettimeofday返回的时间是由struct timeval和struct timezone这两个结构体来共同表示的,其中timeval表示时间,而timezone表示时区。settimeofday是用来设置当前的时间和时区的。


(6)总结:不管用哪个系统调用,最终得到的时间本质上都是一个时间(这个时间最终都是从kernel中记录的jiffies中计算得来的),只不过不同的函数返回的时间的格式不同,精度不同。
 


3.3.3.时间相关API实战1
3.3.3.1、time
(1)time能得到一个当前时间距离标准起点时间1970-01-01 00:00:00 +0000(UTC)过去了多少秒

 实例:  使用 time 第2种 返回值

#include   <stdio.h>
#include <time.h>



int main(void)
{
	time_t tNow = 0;
	
	tNow = time(NULL);  //使用 第 2 种返回值
	
	if(tNow < 0)
	{
		perror("time");
		return -1;
	}
	
	printf("time: %ld \n", tNow);
	
	
	
	return 0;
}

运行结果:

 

 实例:  使用 time 第1种   输出型参数 返回值

代码:

#include   <stdio.h>
#include <time.h>



int main(void)
{
	time_t tNow = -1;
	
	
	time(&tNow);//使用 第 1 种返回值  把地址传进来
	if(tNow < 0)
	{
		perror("time");
		return -1;
	}
	
	printf("time: %ld \n", tNow);
	
	
	
	return 0;
}

运行结果:

用 time 得到的时间 不够直观, 所有用 ctime 来获取时间 

3.3.3.2、ctime
(1)ctime可以从time_t出发得到一个容易观察的字符串格式的当前时间。

#include   <stdio.h>
#include <time.h>



int main(void)
{
	time_t tNow = -1;
	
	
	time(&tNow);//使用 第 1 种返回值  把地址传进来
	if(tNow < 0)
	{
		perror("time");
		return -1;
	}
	
	printf("time: %ld \n", tNow);
	
	printf("ctime: %s \n",ctime(&tNow));  //ctime 直接得到当前 时间
	
	return 0;
}

 运行结果:

 


(2)ctime好处是很简单好用,可以直接得到当前时间的字符串格式,直接打印来看。坏处是ctime的打印时间格式是固定的,没法按照我们的想法去变
(3)实验结果可以看出ctime函数得到的时间是考虑了计算机中的本地时间的(计算机中的时区设置)

3.3.3.3、gmtime和localtime
(1)gmtime获取的时间中:年份是以1970为基准的差值,月份是0表示1月,小时数是以UTC时间的0时区为标准的小时数(北京是东8区,因此北京时间比这个时间大8)

代码:

#include   <stdio.h>
#include <time.h>
#include <string.h>


int main(void)
{
	time_t tNow = -1;
	
	/* 定义一个 gmtime_r  的 结构体变量tm  类型 tmNow变量  */
	struct tm tmNow;
	
	/* time  */
	time(&tNow);//使用 第 1 种返回值  把地址传进来
	
	
	if(tNow < 0)
	{
		perror("time");
		return -1;
	}
	/* time  */
	printf("time: %ld \n", tNow);
	/* ctime   */
	printf("ctime: %s \n",ctime(&tNow));  //ctime 直接得到当前 时间
	
	/* gmtime_r 不可重入函数 ,需要自己分配内存    */
	memset(&tmNow, 0, sizeof(tmNow));//清空 结构体变了 tmNow
	gmtime_r(&tNow, &tmNow);
	
	printf("gmtime_r: %d年 %d月 %d日 一年中多少天%d天 几点%d 时 \n",tmNow.tm_year, tmNow.tm_mon,  tmNow.tm_mday,  tmNow.tm_yday, tmNow.tm_hour  );
	
	
	return 0;
}

运行结果:


(2)猜测localtime和gmtime的唯一区别就是localtime以当前计算机中设置的时区为小时的时间基准,其余一样。实践证明我们的猜测是正确的。

代码:

#include   <stdio.h>
#include <time.h>
#include <string.h>


int main(void)
{
	time_t tNow = -1;
	
	/* 定义一个 gmtime_r  的 结构体变量tm  类型 tmNow变量  */
	struct tm tmNow;
	
	/* time  */
	time(&tNow);//使用 第 1 种返回值  把地址传进来
	
	
	if(tNow < 0)
	{
		perror("time");
		return -1;
	}
	/* time  */
	printf("time: %ld \n", tNow);
	/* ctime   */
	printf("ctime: %s \n",ctime(&tNow));  //ctime 直接得到当前 时间
	
	/* gmtime_r 不可重入函数 ,需要自己分配内存    */
	memset(&tmNow, 0, sizeof(tmNow));//清空 结构体变了 tmNow
	gmtime_r(&tNow, &tmNow);	
	printf("gmtime_r: %d年 %d月 %d日 一年中多少天%d天 几点%d 时 \n",tmNow.tm_year, tmNow.tm_mon,  tmNow.tm_mday,  tmNow.tm_yday, tmNow.tm_hour  );
	
	/* localtime_r 不可重入函数 ,需要自己分配内存    */
    memset(&tmNow, 0, sizeof(tmNow));//清空 结构体变了 tmNow
	localtime_r(&tNow, &tmNow);
	printf("localtime_r: %d年 %d月 %d日 一年中多少天%d天 几点%d 时 \n",tmNow.tm_year, tmNow.tm_mon,  tmNow.tm_mday,  tmNow.tm_yday, tmNow.tm_hour  );
	
	return 0;
}

 

 总结:

1 . 先由 time(&tNow);//使用 第 1 种返回值  把地址传进来

time能得到一个当前时间距离标准起点时间1970-01-01 00:00:00 +0000(UTC)过去了多少秒

 2. 然后才能 printf("ctime: %s \n",ctime(&tNow));  //ctime 直接得到当前 时间

但是 ctime 的时间是固定的 

所以 才需要:   gmtime_r  得到的是 UTC 时间

/* gmtime_r 不可重入函数 ,需要自己分配内存    */
    memset(&tmNow, 0, sizeof(tmNow));//清空 结构体变了 tmNow
    gmtime_r(&tNow, &tmNow); 
    printf("gmtime_r: %d年 %d月 %d日 一年中多少天%d天 几点%d 时 \n",tmNow.tm_year, tmNow.tm_mon,  tmNow.tm_mday,  tmNow.tm_yday, tmNow.tm_hour  );


      localtime_r(&tNow, &tmNow);localtime以当前计算机中设置的时区为小时的时间基准,其余一样

 /* localtime_r 不可重入函数 ,需要自己分配内存    */
    memset(&tmNow, 0, sizeof(tmNow));//清空 结构体变了 tmNow
    localtime_r(&tNow, &tmNow);
    printf("localtime_r: %d年 %d月 %d日 一年中多少天%d天 几点%d 时 \n",tmNow.tm_year, tmNow.tm_mon,  tmNow.tm_mday,  tmNow.tm_yday, tmNow.tm_hour  );
    

代码来自:朱老师物联网大讲堂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大漠飞鹰6666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值