嵌入式Linux系统编程 — 5.2 Linux系统时间与日期

目录

1 了解Linux系统时间

1.1 几种常用的时间

1.2 如何查看几种常用的时间

1.3 Linux 系统中的时间

2 time、gettimeofday获取时间

2.1 time函数

2.2 ​​​​​​​gettimeofday函数:

2.3 示例程序

3 时间转换函数

3.1 ctime与ctime_r函数

3.2 localtime与localtime_r函数

3.3 gmtime和gmtime_r函数

3.4 mktime()函数

3.5 asctime 与asctime_r函数

3.6 strftime 函数

3.7 综合示例

4 设置时间 settimeofday


1 了解Linux系统时间

1.1 几种常用的时间

在正式介绍这些时间、日期相关的系统调用或 C 库函数之前,需要向大家介绍一些时间相关的基本概念,譬如 GMT 时间、 UTC 时间以及时区等。

GMT时间:GMT是格林尼治平均时间,以地球的本初子午线——通过英国伦敦郊区的格林尼治天文台的经线——为基准。GMT是历史上用来确定时间的标准,它不随地球自转速度的变化而调整。

UTC时间:目前国际上用来替代GMT的官方时间标准。UTC使用高精度的原子钟来测量时间,并且可以添加闰秒以保持与地球自转周期的一致性。UTC的主要目的是为了提供一个稳定的时间标准,不受地球自转速度微小变化的影响。

地区时间:实际,世界上不少国家和地区都不严格按时区来计算时间。为了在全国范围内采用统一的时间,一般都把某一个时区的时间作为全国统一采用的时间。例如,我国把首都北京所在的东 8 区的时间作为全国统一的时间,称为北京时间, 北京时间就作为我国使用的本地时间, 譬如我们电脑上显示的时间就是北京时间。

1.2 如何查看几种常用的时间

在 Ubuntu 系统下,可以使用 date 命令查看系统当前的本地时间,可以看到显示出来的字符串后面有一个"CST"字样, CST 在这里其实指的是 China Standard Time(中国标准时间)的缩写,如下所示:

要显示UTC时间,可以使用date -u或者date --utc

1.3 Linux 系统中的时间

"系统时钟"和"实时时钟"

在计算机系统中,"系统时钟"(System Clock)和"实时时钟"(Real Time Clock, RTC)是两种不同类型的时钟,它们有不同的用途和特性:

系统时钟(System Clock):

  • 系统时钟是计算机的主时钟,用于跟踪当前的日期和时间。它通常由操作系统管理,并且可以受到用户设置和网络时间协议(NTP)的影响。
  • 系统时钟可能会因为多种原因(如系统休眠或时间同步)而调整或变化。

实时时钟(Real Time Clock, RTC):

  • 实时时钟是一种独立于主系统的时钟,通常由一个小型电池供电,即使在计算机关机时也能保持时间。RTC用于在系统启动时设置系统时钟,并在系统运行时提供准确的时间参考。
  • RTC通常具有较低的精度,但能够在没有外部电源的情况下保持时间,使其成为记录系统启动时间和维护系统时间连续性的关键组件。

jiffies 的引入

Jiffies是Linux内核中用于时间度量的一个概念,它是一个自系统启动以来的计时器,以固定频率递增。每个jiffy的长度取决于系统的时钟频率,通常在不同系统上会有所不同,但大约相当于几毫秒。Jiffies被用来测量系统的运行时间、调度任务和执行时间相关的计算。由于jiffies与实际时间的秒数不是固定比例,它主要用于内核内部的时间管理,而不是用来获取精确的日期和时间。

2 time、gettimeofday获取时间

timegettimeofday 是两个在Linux系统中用于获取时间的函数,分别定义在 <time.h><sys/time.h> 头文件中。

2.1 time函数

time 函数用于获取自1970年1月1日(UTC)以来经过的秒数,函数原型:

#include <time.h>time_t time(time_t *t);
  • 如果 t 参数不为 NULLtime 函数还会将当前时间戳复制到 t 指向的位置。
  • 返回值是当前时间的时间戳,如果出现错误,则返回 -1 并设置 errno

2.2 ​​​​​​​gettimeofday函数

time()获取到的时间只能精确到秒,如果想要获取更加精确的时间可以使用系统调用 gettimeofday 来实现, gettimeofday()函数提供微秒级时间精度,函数原型如下所示:

#include <sys/time.h>int gettimeofday(struct timeval *tv, struct timezone *tz);
  • 参数 tv 指向一个 timeval 结构,该结构将被填充当前时间的秒和微秒。
  • 参数 tz 指向一个 timezone 结构,如果提供,它将被填充关于本地时区的信息。

2.3 示例程序

以下是使用 timegettimeofday 函数的示例:

#include <stdio.h>
#include <time.h>
#include <sys/time.h>int main() {// 使用 time 函数获取当前时间戳time_t current_time = time(NULL);printf("Current UNIX timestamp: %ld\n", current_time);// 使用 gettimeofday 函数获取当前的日期和时间struct timeval now;if (gettimeofday(&now, NULL) == 0) {printf("Current date and time: %ld.%06ld\n", now.tv_sec, (long)now.tv_usec);} else {perror("gettimeofday failed");}return 0;
}

运行结果如下: 

3 时间转换函数

通过 time()或 gettimeofday()函数可以获取到当前时间点相对于 1970-01-01 00:00:00 +0000(UTC)这个时间点所经过时间(日历时间) ,所以获取得到的是一个时间段的长度,但是这并不利于我们查看当前时间,下面介绍一些系统调用或 C 库函数,通过这些 API 可以将 time()或gettimeofday()函数获取到的秒数转换为利于查看和理解的形式。

3.1 ctime与ctime_r函数

ctime()是一个 C 库函数, 可以将日历时间转换为可打印输出的字符串形式, ctime()函数原型如下所示:

#include <time.h>char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);
  • ctime函数将时间戳(以 time_t 类型表示)转换为一个以null结尾的字符串,格式为"Thu Jan 01 00:00:00 1970\n\0"。这个函数不是线程安全的,因为它只返回一个静态缓冲区的指针。
  • ctime_r函数与 ctime 功能相同,但它是线程安全的,因为它将结果写入由调用者提供的缓冲区 buf,推荐大家使用可重入函数 ctime_r()。

3.2 localtime与localtime_r函数

localtime()函数可以把 time()或 gettimeofday()得到的秒数(time_t 时间或日历时间) 变成一个 struct tm结构体所表示的时间, 该时间对应的是本地时间。 localtime 函数原型如下:

#include <time.h>struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
  • localtime函数:返回一个指向静态分配的 struct tm 的指针,该结构包含了转换后的本地时间。意味着每次调用 localtime 都会覆盖上一次调用的结果,因此它不是线程安全的。
  • localtime_r函数:接受两个参数,第一个是指向 time_t 的指针,第二个是指向由调用者提供的 struct tm 结构的指针。转换的结果将直接存储在 result 指向的结构中。由于结果存储在调用者提供的存储空间中,因此 localtime_r 可以安全地被多个线程使用,而不会相互干扰。

struct tm 结构体如下所示:

struct tm {int tm_sec; /* 秒(0-60) */int tm_min; /* 分(0-59) */int tm_hour; /* 时(0-23) */int tm_mday; /* 日(1-31) */int tm_mon; /* 月(0-11) */int tm_year; /* 年(这个值表示的是自 1900 年到现在经过的年数) */int tm_wday; /* 星期(0-6, 星期日 Sunday = 0、星期一=1…) */int tm_yday; /* 一年里的第几天(0-365, 1 Jan = 0) */int tm_isdst; /* 夏令时 */
};

3.3 gmtime和gmtime_r函数

gmtimegmtime_r 函数都用于将Linux时间戳转换为UTC的日期和时间,并不是计算机的本地时间,这是 与localtime的唯一区别,函数原型如下所示:

#include <time.h>struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);

3.4 mktime()函数

mktime()函数与 localtime()函数相反, mktime()可以将使用 struct tm 结构体表示的分解时间转换为 time_t时间(日历时间) ,同样这也是一个 C 库函数,其函数原型如下所示:

#include <time.h>time_t mktime(struct tm *tm);
  • tm: 需要进行转换的 struct tm 结构体变量对应的指针。

3.5 asctime 与asctime_r函数

asctime()函数与 ctime()函数的作用一样,也可将时间转换为可打印输出的字符串形式,与 ctime()函数的区别在于, ctime()是将 time_t 时间转换为固定格式字符串、而 asctime()则是将 struct tm 表示的分解时间转换为固定格式的字符串。 asctime()函数原型如下所示:

#include <time.h>char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);
  • tm: 需要进行转换的 struct tm 表示的时间。
  • buf: 可重入版本函数 asctime_r 需要额外提供的参数 buf,指向一个缓冲区,用于存放转换得到的字符串。

3.6 strftime 函数

strftime()函数也可以将一个 struct tm 变量表示的分解时间转换为为格式化字符串,并且在功能上比 asctime()和 ctime()更加强大,它可以根据自己的喜好自定义时间的显示格式,strftime()函数原型如下所示:

#include <time.h>size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
  • s: 指向一个缓存区的指针,该缓冲区用于存放生成的字符串。
  • max: 字符串的最大字节数。
  • format: 这是一个用字符串表示的字段, 包含了普通字符和特殊格式说明符,可以是这两种字符的任意组合。 特殊格式说明符将会被替换为 struct tm 结构体对象所指时间的相应值,

    以下是 strftime 函数的一些常见格式化指令:

%a:星期的缩写名。
%A:星期的全名。

%b:月份的缩写名。

%B:月份的全名。

%c:适合人类阅读的日期和时间。

%d:一个月中的第几天(01-31)。

%H:小时(24小时制,00-23)。

%I:小时(12小时制,01-12)。

%m:月份(01-12)。

%M:分钟(00-59)。

%p:AM或PM。

%S:秒(00-59)。

%Y:四位数的年份。

3.7 综合示例

下面的示例使用 ctime_rlocaltime_rgmtime_rmktimeasctime_rstrftime 函数演示了如何安全地获取当前时间,转换为本地时间、UTC时间,以及如何格式化时间字符串。

#include <stdio.h>
#include <time.h>int main() 
{time_t rawtime;struct tm result_tm;char buffer[26]; // 足够存储 "Wed Jan 03 09:06:15 1984\n\0" 的长度// 获取当前时间戳time(&rawtime);// 使用 ctime_r 安全地转换时间戳为本地时间字符串if (ctime_r(&rawtime, buffer) != NULL) {printf("Current time (ctime_r): %s", buffer);}// 使用 localtime_r 安全地转换时间戳为本地tm结构if (localtime_r(&rawtime, &result_tm) != NULL) {printf("Local time (localtime_r): %d-%02d-%02d %02d:%02d:%02d\n",result_tm.tm_year + 1900, result_tm.tm_mon + 1,result_tm.tm_mday, result_tm.tm_hour,result_tm.tm_min, result_tm.tm_sec);}// 使用 gmtime_r 安全地转换时间戳为UTC tm结构if (gmtime_r(&rawtime, &result_tm) != NULL) {printf("UTC time (gmtime_r): %d-%02d-%02d %02d:%02d:%02d\n",result_tm.tm_year + 1900, result_tm.tm_mon + 1,result_tm.tm_mday, result_tm.tm_hour,result_tm.tm_min, result_tm.tm_sec);}// 使用 mktime 将本地tm结构转换为时间戳rawtime = mktime(&result_tm);if (rawtime == (time_t)-1) {perror("mktime failed");} else {printf("Time stamp (mktime): %ld\n", rawtime);}// 使用 asctime_r 安全地转换tm结构为本地时间字符串if (asctime_r(&result_tm, buffer) != NULL) {printf("Time (asctime_r): %s", buffer);}// 使用 strftime 格式化日期和时间if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &result_tm) > 0) {printf("Formatted time (strftime): %s\n", buffer);}return 0;
}

​​​​​​​运行结果如下:

4 设置时间 settimeofday

settimeofday 是一个在 Linux系统中使用的系统调用,用于设置当前的UTC时间和时钟的微秒部分。函数原型如下:

#include <sys/time.h>int settimeofday(const struct timeval *tv, const struct timezone *tz);
  • tv:指向 struct timeval 的指针,包含了新的秒和微秒值。
  • tz:指向 struct timezone 的指针,包含了关于时区的信息,比如夏令时的偏移量。如果不需要设置时区,这个参数可以设置为 NULL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/36874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity之自定义Text组件默认属性值

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之自定义Text组件默认属性值 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01;…

普通集群与镜像集群配置

一. 环境准备 关闭防火墙和selinux&#xff0c;进行时间同步 rabbitmq-1 Rocky_linux9.4 192.168.226.22rabbitmq-2Rocky_linux9.4192.168.226.23rabbitmq-3Rocky_linux9.4192.168.226.24 修改主机名#192.168.226.22 hostnamectl set-hostname rabbitmq-1#192.168.226.22 ho…

isalpha()方法——判断字符串是否只由字母组成

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 isalpha()方法用于判断字符串是否只由字母组成。isalpha()方法的格式如下&#xff1a; str.isalpha() 如果字符串中至少有一个字符并且所…

「C++系列」C++ 基本语法

文章目录 一、C 基本语法1. **预处理指令**2. **数据类型**3. **变量和常量**4. **运算符**5. **控制流语句**6. **函数**7. **数组**8. **指针和引用**9. **结构体和类**10. **输入/输出**11. **异常处理**12. **命名空间** 二、C 程序结构1. 程序流程结构2. 文件结构3. 编译预…

MySQL之聚簇索引和非聚簇索引

1、什么是聚簇索引和非聚簇索引&#xff1f; 聚簇索引&#xff0c;通常也叫聚集索引。 非聚簇索引&#xff0c;指的是二级索引。 下面看一下它们的含义&#xff1a; 1.1、聚集索引选取规则 如果存在主键&#xff0c;主键索引就是聚集索引。如果不存在主键&#xff0c;将使…

【Lua】第二篇:打印函数和注释

文章目录 一. 打印函数二. 注释方式1. 单行注释2. 多行注释 一. 打印函数 Lua 程序是以 .lua 结尾的文件&#xff0c;创建一个的 Test.lua 的文件&#xff0c;使用 print 函数输出字符串"Hello World"&#xff1a; print(Hello World) 保存之后使用命令lua 文件名编…

Java | Leetcode Java题解之第206题反转链表

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode reverseList(ListNode head) {if (head null || head.next null) {return head;}ListNode newHead reverseList(head.next);head.next.next head;head.next null;return newHead;} }

SpringBoot学习04-[定制SpringMVC]

定制SpringMVC 定制SpringMvc的自动配置定制springmvc-configurePathMatch配置定制SpringMVC-拦截器Interceptor定制SpringMVC-CORS配置全局cors配置针对某个方法加跨域解决 WebMvcConfigurer原理定制SpringMVC-JSONJSON开发jackson的使用定制化json序列化和反序列化 JSON国际化…

CriticGPT: 用 GPT-4 找出 GPT-4 的错误

CriticGPT 是 OpenAI 发布的一个基于 GPT-4 的模型&#xff0c;它可以帮助我们人类 Review 并纠正 ChatGPT 在生成代码时的错误。使用 CriticGPT 审查代码时&#xff0c;有 60% 的概率生成的代码更好更正确。

最近写javaweb出现的一个小bug---前端利用 form 表单传多项数据,后端 Servlet 取出的各项数据均为空

目录&#xff1a; 一. 问题引入二 解决问题 一. 问题引入 近在写一个 java web 项目时&#xff0c;遇到一个让我头疼了晚上的问题&#xff1a;前端通过 post 提交的 form 表单数据可以传到后端&#xff0c;但当我从 Servlet 中通过 request.getParameter(“name”) 拿取各项数…

【小沐学AI】Python实现语音识别(faster-whisper-webui)

文章目录 1、简介1.1 whisper1.2 faster-whisper 2、安装3、测试结语 1、简介 1.1 whisper https://github.com/openai/whisper Whisper 是一种通用语音识别模型。它是在各种音频的大型数据集上训练的&#xff0c;也是一个多任务模型&#xff0c;可以执行多语言语音识别、语音…

【JVM基础篇】垃圾回收

文章目录 垃圾回收常见内存管理方式手动回收&#xff1a;C内存管理自动回收(GC)&#xff1a;Java内存管理自动、手动回收优缺点 应用场景垃圾回收器需要对哪些部分内存进行回收&#xff1f;不需要垃圾回收器回收需要垃圾回收器回收 方法区的回收代码测试手动调用垃圾回收方法Sy…

Matlab|分时电价环境下用户负荷需求响应分析方法

主要内容 本程序复现《分时电价环境下用户负荷需求响应分析方法》文献中的方法&#xff0c;通过用户对不同时间下用电需求的自弹性和交叉弹性系数分析获得用户需求响应矩阵&#xff0c;进而利用该矩阵对用户在实行基于电价的需求侧管理后的负荷变化情况进行快速分析。 1.1…

ONLYOFFICE8.1版本桌面编辑器简单测评

ONLYOFFICE官网链接&#xff1a;在线PDF查看器和转换器 | ONLYOFFICE ONLYOFFICE介绍&#xff1a;https://www.onlyoffice.com/zh/office-suite.aspx OnlyOffice 是一款免费且开源的 Office 协作办公套件&#xff0c;支持桌面端和移动端等多平台&#xff0c;由一家领先的 IT 公…

【python】OpenCV—Aruco

文章目录 Detect ArucoGuess Aruco Type Detect Aruco 学习参考来自&#xff1a;OpenCV基础&#xff08;19&#xff09;使用 OpenCV 和 Python 检测 ArUco 标记 更多使用细节可以参考&#xff1a;【python】OpenCV—Color Correction 源码&#xff1a; 链接&#xff1a;http…

为什么IP地址会被列入黑名单?

您是否曾经历过网站访客数量骤减或电子邮件投递失败的困扰&#xff1f;这背后或许隐藏着一个常被忽略的原因&#xff1a;您的IP地址可能已经被列入了黑名单内。尽管您并没有进行任何违法的网络操作&#xff0c;但这个问题依然可能出现。那么&#xff0c;究竟黑名单是什么&#…

【VMware】VMware 开启的虚拟机无法联网的解决方案

目录 &#x1f30a;1. 问题说明 &#x1f30a;2. 解决方案 &#x1f30d;2.1 查看虚拟网络编辑器 &#x1f30d;2.2 设置 vmnet &#x1f30d;2.3 设置虚拟机网络 &#x1f30d;2.4 Xshell连接虚拟机 &#x1f30a;1. 问题说明 虚拟机 ping 其他网页显示失败,比如&#…

数据质量管理-时效性管理

前情提要 根据GB/T 36344-2018《信息技术 数据质量评价指标》的标准文档&#xff0c;当前数据质量评价指标框架中包含6评价指标&#xff0c;在实际的数据治理过程中&#xff0c;存在一个关联性指标。7个指标中存在4个定性指标&#xff0c;3个定量指标&#xff1b; 定性指标&am…

【旭日x3派】部署官方yolov5全流程

地平线旭日x3派部署yolov5--全流程 前言一、深度学习环境安装二、安装docker三、部署3.1、安装工具链镜像3.2、配置天工开物OpenExplorer工具包3.3、创建深度学习虚拟空间&#xff0c;安装依赖&#xff1a;3.4、下载yolov5项目源码并运行3.5、pytorch的pt模型文件转onnx3.6、最…

前端git约定式规范化提交-commitizen

当使用commitizen进行代码提交时&#xff0c;commitizen会提示你在提交代码时填写所必填的提交字段信息内容。 1、全局安装commitizen npm install -g commitizen4.2.4 2、安装并配置 cz-customizeable 插件 2.1 使用 npm 下载 cz-customizeable npm i cz-customizeable6.…