LInux 时间函数相关操作

发布时间:2023年12月29日

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;
}
文章来源:https://blog.csdn.net/weixin_46999174/article/details/135209646
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。