12_Linux时间处理操作
Linux时间处理函数
- 时间类常用结构体
- time_t 秒级
- struct timespec 秒级和纳秒级结构体
- struct timeval 秒级和微秒级结构体
- struct tm 转换分解后的时间结构体
- struct itimerspec 定时器的结构体值
- localtime获取的数据存储问题
时间类常用结构体
time_t 秒级
time_t 是一个整数类型,用于表示从 Unix 纪元(1970 年 1 月 1 日 00:00:00 UTC)开始的秒数。它是时间戳的标准表示形式。
time_t rawtime;
time(&rawtime); // 获取当前时间的时间戳
struct timespec 秒级和纳秒级结构体
struct timespec 用于表示高精度的时间,包括秒和纳秒。
struct timespec {time_t tv_sec; // 秒long tv_nsec; // 纳秒
};struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); // 获取当前时间
struct timeval 秒级和微秒级结构体
struct timeval 用于表示微秒级的时间,常用于计时和超时操作。
struct timeval {time_t tv_sec; // 秒suseconds_t tv_usec; // 微秒
};struct timeval tv;
gettimeofday(&tv, NULL); // 获取当前时间
struct tm 转换分解后的时间结构体
struct tm 代表一个分解的时间结构体,包含了年、月、日、小时、分钟、秒等各个组成部分。通常通过 localtime 或 gmtime 从 time_t 类型的时间戳转换而来。
#include <time.h>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] (周日为 0)int tm_yday; // 一年中的第几天 [0, 365]int tm_isdst; // 夏令时标志
};struct tm * timeinfo;
time_t rawtime;time(&rawtime);
timeinfo = localtime(&rawtime); // 转换为本地时间
struct itimerspec 定时器的结构体值
struct itimerspec 用于表示定时器的值,包括定时器的到期时间和周期。
struct itimerspec {struct timespec it_interval; // 定时器重复触发的时间间隔struct timespec it_value; // 定时器首次触发前等待的时间
};struct itimerspec timer;
// 设置定时器
timer.it_value.tv_sec = 5; // 定时器首次触发前等待的时间
timer.it_value.tv_nsec = 0; // 纳秒部分
timer.it_interval.tv_sec = 1; // 定时器重复触发的时间间隔
timer.it_interval.tv_nsec = 0; // 纳秒部分
示例:使用select监听定时文件描述符是否到达时间
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/timerfd.h>
#include <time.h>
#include <string.h>
#include <inttypes.h>
#include <sys/select.h>int main() {int timerfd;struct itimerspec timer;char buf[8]; // 事件通知的大小为 8 字节uint64_t count; // 存储读取的计数值// 创建定时器文件描述符timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);if (timerfd == -1) {perror("timerfd_create");exit(EXIT_FAILURE);}// 设置定时器首次触发前等待的时间(it_value)和重复触发的时间间隔(it_interval)timer.it_value.tv_sec = 5; // 定时器首次触发前等待 5 秒timer.it_value.tv_nsec = 0; // 纳秒部分timer.it_interval.tv_sec = 3; // 定时器重复触发的时间间隔为 1 秒timer.it_interval.tv_nsec = 0; // 纳秒部分if (timerfd_settime(timerfd, 0, &timer, NULL) == -1) {perror("timerfd_settime");close(timerfd);exit(EXIT_FAILURE);}fd_set fds;struct timeval timeout;// 监听定时器事件while (1) {FD_ZERO(&fds);FD_SET(timerfd, &fds);timeout.tv_sec = 1; // 超时时间为 1 秒timeout.tv_usec = 0;if (select(timerfd + 1, &fds, NULL, NULL, &timeout) == -1) {perror("select");close(timerfd);exit(EXIT_FAILURE);}if (FD_ISSET(timerfd, &fds)) {ssize_t n = read(timerfd, buf, sizeof(buf));if (n != sizeof(buf)) {perror("read");close(timerfd);exit(EXIT_FAILURE);}memcpy(&count, buf, sizeof(count));printf("Timer expired, count: %" PRIu64 "\n", count);}}close(timerfd);return 0;
}
localtime获取的数据存储问题
localtime获得的时间数据存储在栈上的固定位置,每次调用该函数,都会更新该值,为了防止出错,需要拷贝出来,示例:
#include <string.h>
#include <inttypes.h>
#include <sys/select.h>int main() {time_t time_now;struct tm* tm;time(&time_now);tm = localtime(&time_now);printf("第一次:%d-%d-%d %d:%d:%d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);sleep(10);time(&time_now);localtime(&time_now);printf("第二次:%d-%d-%d %d:%d:%d\n", tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);return 0;
}
结果: