LInux 时间函数相关操作
Linux相关时间操作
1.时间概念
国际时间 GMT格林威治标准时间用来描述全球性的事件的时间,方便大家记忆。为了方便,一个国家都统一使用一个当地时间。这些年都开始使用UTC时间。 UTC加时区差等于本地时间。
Linux 系统中的时间
1.jiffies的引入
(1)jiffies 是LInux内核的全局变量,这个变量用来记录以jiffies为单位时间长度的一个数值。
(2)内核配置的时候定义了一个节拍时间,实际上LInux内核的调度系统工作时就是以节拍时间为时间片的。
(3)jiffies变量开机的时候有一个基准值,然后内核每过一个节拍时间jiffies就会加一,然后到了系统的任意一个时间,我们当前时间就会被jiffies这个变量所标注。
2.linux系统如何记录时间
(1)内核在开机启动的时候就会读取RTC硬件获取一个时间作为初始化基准时间,这个基准时间对应一个jiffies值(这个基准时间换算为jiffies值的方法是:用这个时间减去 1970 00:00:00 然后把这个时间段换算为jiffies数值,然后系统运行的时候每个时钟节拍的末尾都会给jiffies这个全局变量加一,因此操作系统使用jiffies这个全局变量记录下了当前的时间,当我们需要当前时间点的时候 ,就用jiffies这个时间点去计算,(计算方法就是先把这个这个jiffies值对应的时间段算出来,然后加上 1970 00:00:00 即可得到这个时间点)
(2)其实操作系统运行的时候只在主机读一次RTC,整个操作系统运行过程中RTC是无作用的,RTC的真正的作用是在OS两次保存,一个时间节拍的时间取决于操作系统的配置, 现代Linux系统一般是10ms或者1ms。这个时间其实就是调度时间,内核中用HZ来记录和表示,如何HZ定义成1000那么时钟节拍就是1/HZ 也就是1ms 。
LInux中时间相关的系统调用
time/ctime/localtime/gmtime/mktime/asctime
- time 系统调用返回当前时间以秒为单位的距离1970-01-01 00:00:00 +0000 (UTC)过去的秒数。这个time 内部就是用jiffies换算得到的秒数。其他函数基本上围绕time 来工作的。
- localtime函数将以秒为单位的时间值转换为包含日期和时间信息的结构体(struct tm),表示为本地时区的时间。它考虑了系统设置的本地时区和夏令时调整,并将时间值转换为对应本地时区的日期和时间。
- gmtime函数将以秒为单位的时间值转换为包含日期和时间信息的结构体(struct tm),表示为协调世界时(UTC)的时间。它不考虑时区或夏令时调整,将时间值转换为对应于协调世界时的日期和时间。
struct tm {
int tm_sec; // 秒(0-59)
int tm_min; // 分钟(0-59)
int tm_hour; // 小时(0-23)
int tm_mday; // 一个月中的日期(1-31)
int tm_mon; // 月份(0-11,0 表示一月)
int tm_year; // 年份,从 1900 年开始计算
int tm_wday; // 一周中的星期几(0-6,0 表示周日)
int tm_yday; // 一年中的第几天(0-365,0 表示 1 月 1 日)
int tm_isdst; // 夏令时标志(负数表示信息不可用)
};
- mktime 可以将包含日期和时间信息的 struct tm 结构体转换为一个表示相同时间的秒数(从 1970 年 1 月 1 日 00:00:00 UTC 开始计算)的 time_t 类型值。
- 如果从struct tm 出发想得到字符串格式的时间,可以用asctime 或 strftime 如果想从time_t 得到字符串格式的时间 可以用ctime
- gettimeinfoday 返回的时间是由struct timeval 和struct timezone 这个两个结构体共同表示的,其中timeval表示时间,而timezone表示时区。settimeofday 是用来设置当前的时间和时区的。
- 总结:不管用哪个系统调用,最终得到的时间本质上都是一个时间(这个时间最终都是kernel中记录的)
时间相关API Demo
time调用
#include <stdio.h>
#include <time.h>
int main() {
time_t tnow = -1;
// tnow = time(NULL);
time(&tnow);
if (tnow == -1) {
perror("time");
return -1;
}
printf("time: %ld\n", tnow);
return 0;
}
Ubuntu系统上不会报错 在Deepin系统 用指针传值会报错
time能得到一个当前时间距离标准起点时间过去了多少秒
printf("current time :%s",ctime(&tnow));
ctime 能得到当前Linux 系统时间 传入 time_t 参数,好处是很简单很好用,可以得到当前时间的字符串格式、坏处是打印的格式是固定的 没法按照我们想要的时间格式。实验结果可以看出ctime 函数得到的时间是考虑了计算机的本地时间。
gmtime和localtime
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
int main() {
time_t tnow = -1;
struct tm tmNow;
// tnow = time(NULL);
time(&tnow);
if (tnow == -1) {
perror("time");
return -1;
}
printf("time: %ld\n", tnow);
printf("current time :%s",ctime(&tnow));
memset(&tmNow,0,sizeof(tmNow));
gmtime_r(&tnow,&tmNow);
printf("%d year,%d month,%d day\n",tmNow.tm_year+1900,tmNow.tm_mon,tmNow.tm_yday);
//year base on 1900 yday is day in year
return 0;
}
mktime
从os读取时间时候一般用不到mktime的,这个mktime 是用来向OS设置时间用的
asctime: 将时间结构体转换为固定格式的字符串
time_t tnow = -1;
struct tm tmNow;
memset(&tmNow,0,sizeof(tmNow));
localtime_r(&tnow,&tmNow);
printf("%d year,%d month,%d day\n",tmNow.tm_year+1900,tmNow.tm_mon,tmNow.tm_yday);
char* timeString = asctime(&tmNow); // 将 struct tm 结构体转换为字符串格式
printf("strTime is [%s]",timeString);
strftime:格式更加灵活 可以自己定义格式
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
int main() {
time_t tnow = -1;
struct tm tmNow;
memset(&tmNow,0,sizeof(tmNow));
localtime_r(&tnow,&tmNow);
printf("%d year,%d month,%d day\n",tmNow.tm_year+1900,tmNow.tm_mon,tmNow.tm_yday);
char* timeString = asctime(&tmNow); // 将 struct tm 结构体转换为字符串格式
printf("strTime is [%s]",timeString);
char buffer[80]; // 用于存储格式化后的时间字符串
memset(&buffer,0,sizeof(buffer));
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tmNow);
// 格式化时间并存储到 buffer 中,格式为 "年-月-日 时:分:秒"
printf("Formatted time: %s\n", buffer);
return 0;
}
gettimeofday 和settimeofday
gettimeofday() 和 settimeofday() 是 POSIX 系统中用于获取和设置时间的函数,通常在Unix/Linux 等操作系统中使用。
struct timeval {
long tv_sec; // 秒
long tv_usec; // 微秒
};
#include <stdio.h>
#include <sys/time.h>
int main() {
struct timeval tv;
if (gettimeofday(&tv, NULL) == 0) {
printf("Seconds: %ld, Microseconds: %ld\n", tv.tv_sec, tv.tv_usec);
} else {
perror("gettimeofday");
}
return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!