C 标准库 <time.h> 函数详解

目录

概述

1 核心数据类型

1.1 time_t

 1.2 clock_t

1.3 struct tm

1.4 size_t

2 核心函数

2.1 时间获取函数

2.2 时间转换函数

2.3 时间差计算

2.4  时间格式化函数

3 线程安全版本(POSIX 扩展)

3.1 函数列表 

 3.2 时间处理完整示例

4 重要注意事项

5 实际应用场景

5.1 日志记录

5.2 定时任务

5.3 性能分析

5.4 时间戳转换

6 Nordic MCU上验证


概述

本文主要介绍C 标准库 <time.h> 函数,<time.h> 是 C 语言中处理时间和日期的标准库,提供了一系列函数和数据类型用于时间获取、转换和格式化操作提供了一套完整的时间处理工具链,尽管在精度和时区处理上有一定限制,但对于大多数应用场景已经足够。在开发跨平台应用时,应注意不同系统对线程安全和时区支持的差异。

1 核心数据类型

1.1 time_t

  • 描述:表示日历时间的算术类型(通常为整数)

  • 特性

  • 存储从 "纪元"(通常为 1970-01-01 00:00:00 UTC)起经过的秒数

  • 在 32 位系统上最大值为 2038-01-19 03:14:07(Y2038 问题)

  • 64 位系统可表示约 2920 亿年的时间范围

 1.2 clock_t

  • 描述:表示处理器时间的算术类型

  • 用途:测量程序执行时间(CPU 时间)

1.3 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](0=一月)int tm_year;  // 年份(从1900开始的年数)int tm_wday;  // 星期几 [0-6](0=周日)int tm_yday;  // 年中的日 [0-365]int tm_isdst; // 夏令时标志:>0(生效)、0(不生效)、<0(未知)
};

1.4 size_t

  • 用于 strftime 函数表示缓冲区大小

2 核心函数

2.1 时间获取函数

1) time_t time(time_t *timer)

  • 功能:获取当前日历时间

  • 参数

    • timer:存储结果的指针(可为 NULL)

  • 返回

    • 成功:当前时间(从纪元开始的秒数)

    • 失败:(time_t)(-1)

time_t now;
now = time(NULL);  // 获取当前时间

2) clock_t clock(void)

  • 功能:获取程序使用的处理器时间

  • 返回

    • 成功:从程序启动开始的 CPU 时间(时钟滴答数)

    • 失败:(clock_t)(-1)

  • 注意:需除以 CLOCKS_PER_SEC 转换为秒

clock_t start = clock();
// 执行代码...
clock_t end = clock();
double cpu_time = (double)(end - start) / CLOCKS_PER_SEC;

2.2 时间转换函数

1) struct tm *gmtime(const time_t *timer);

  • 功能:将日历时间转换为 UTC 时间

  • 参数timer - 指向日历时间的指针

  • 返回:指向静态 tm 结构的指针(非线程安全)

time_t now = time(NULL);
struct tm *utc_time = gmtime(&now);

 2) struct tm *localtime(const time_t *timer);

  • 功能:将日历时间转换为本地时间(考虑时区和夏令时)

  • 参数timer - 指向日历时间的指针

  • 返回:指向静态 tm 结构的指针(非线程安全)

time_t now = time(NULL);
struct tm *local_time = localtime(&now);

3) time_t mktime(struct tm *timeptr);

  • 功能:将本地时间转换为日历时间

  • 特性

    • 自动规范化超出范围的字段

    • 计算并填充 tm_wday 和 tm_yday

    • 正确处理夏令时

struct tm new_year = {0};
new_year.tm_year = 124; // 2024年(2024-1900)
new_year.tm_mon = 0;    // 一月
new_year.tm_mday = 1;   // 1号
time_t timestamp = mktime(&new_year);

2.3 时间差计算

double difftime(time_t time1, time_t time0);

  • 功能:计算两个日历时间的差值(秒)

  • 返回time1 - time0(以秒为单位的双精度值)

time_t start = time(NULL);
// 执行操作...
time_t end = time(NULL);
double elapsed = difftime(end, start);

2.4  时间格式化函数

1) char *asctime(const struct tm *timeptr);

  • 功能:将 tm 结构转换为固定格式字符串

  • 格式"Day Mon dd hh:mm:ss yyyy\n"

  • 返回:指向静态缓冲区的指针(非线程安全)

struct tm *t = localtime(&now);
printf("Current: %s", asctime(t));
// 输出示例:Tue Jun 18 14:30:45 2024

2) char *ctime(const time_t *timer);

  • 功能:将日历时间转换为本地时间字符串

  • 等效asctime(localtime(timer))

  • 返回:指向静态缓冲区的指针(非线程安全)

time_t now = time(NULL);
printf("Current: %s", ctime(&now));

3) size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr);

  • 功能:自定义格式化时间输出

  • 参数

    • str:输出缓冲区

    • maxsize:缓冲区最大容量

    • format:格式字符串

    • timeptr:指向 tm 结构的指针

  • 返回:写入字符数(不包括终止空字符),失败返回0

常用格式说明符

说明符含义示例
%Y四位年份2024
%y两位年份24
%m月份(01-12)06
%d月中的日(01-31)18
%H24小时制小时(00-23)14
%I12小时制小时(01-12)02
%M分钟(00-59)30
%S秒(00-60)45
%A完整星期名Tuesday
%a缩写星期名Tue
%B完整月份名June
%b缩写月份名Jun
%pAM/PMPM
%Z时区名CST
%zUTC偏移(+HHMM)+0800
%FISO 8601日期格式2024-06-18
%TISO 8601时间格式14:30:45

char buffer[80];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S %Z", localtime(&now));
printf("Formatted: %s\n", buffer); // 2024-06-18 14:30:45 CST

3 线程安全版本(POSIX 扩展)

3.1 函数列表 

标准函数线程安全版本
gmtimegmtime_r
localtimelocaltime_r
asctimeasctime_r
ctimectime_r

使用案例:

// 线程安全用法示例
struct tm result;
localtime_r(&now, &result);char buffer[80];
asctime_r(&result, buffer);

 3.2 时间处理完整示例

#include <stdio.h>
#include <time.h>int main() {// 获取当前时间time_t now = time(NULL);// 转换为本地时间struct tm *local = localtime(&now);printf("当前时间: %s", asctime(local));// 自定义格式化char time_str[100];strftime(time_str, sizeof(time_str), "今天是 %Y年%m月%d日 %A", local);printf("%s\n", time_str);// 计算未来时间struct tm future = *local;future.tm_mday += 30; // 30天后mktime(&future); // 规范化时间strftime(time_str, sizeof(time_str), "30天后: %Y-%m-%d %H:%M:%S", &future);printf("%s\n", time_str);// 测量CPU时间clock_t start = clock();for (volatile long i = 0; i < 1000000000; i++); // 耗时循环clock_t end = clock();printf("CPU时间: %.2f秒\n", (double)(end - start) / CLOCKS_PER_SEC);// 计算时间差time_t end_time = time(NULL);printf("实际时间: %.2f秒\n", difftime(end_time, now));return 0;
}

4 重要注意事项

  1. 非线程安全性

    • gmtimelocaltimeasctimectime 使用静态缓冲区

    • 多线程环境中应使用 _r 后缀的线程安全版本

  2. 时区处理

    • 时区信息通常来自系统环境变量 TZ

    • 可使用 tzset() 函数(POSIX)初始化时区设置

  3. Y2038 问题

    • 32 位系统的 time_t 在 2038 年会溢出

    • 解决方案:使用 64 位系统或专门的时间库

  4. 夏令时处理

    • localtime 和 mktime 自动处理夏令时

    • 设置 tm_isdst = -1 让系统自动确定

  5. 精度限制

    • 标准时间函数精度通常为秒级

    • 更高精度需求需使用平台特定 API(如 POSIX clock_gettime()

5 实际应用场景

5.1 日志记录

void log_message(const char *msg) {time_t now = time(NULL);char time_str[30];strftime(time_str, sizeof(time_str), "[%Y-%m-%d %H:%M:%S]", localtime(&now));printf("%s %s\n", time_str, msg);
}

5.2 定时任务

void daily_task() {time_t now = time(NULL);struct tm *t = localtime(&now);// 每天凌晨2点执行if (t->tm_hour == 2 && t->tm_min == 0) {perform_maintenance();}
}

5.3 性能分析

void profile_function() {clock_t start = clock();// 被分析的函数expensive_operation();clock_t end = clock();printf("CPU时间: %.4f秒\n", (double)(end - start) / CLOCKS_PER_SEC);
}

5.4 时间戳转换

time_t parse_iso8601(const char *str) {struct tm tm = {0};sscanf(str, "%d-%d-%dT%d:%d:%d",&tm.tm_year, &tm.tm_mon, &tm.tm_mday,&tm.tm_hour, &tm.tm_min, &tm.tm_sec);tm.tm_year -= 1900;tm.tm_mon -= 1;tm.tm_isdst = -1;return mktime(&tm);
}

6 Nordic MCU上验证

源代码:

/* USER CODE BEGIN Header */
/********************************************************************************* File Name        :  app_rtc.c* Description      :  define the macro parameters******************************************************************************* @attention**  COPYRIGHT:    Copyright (c) 2025  mingfei_tang*  DATE:         MAR 27th, 2025*******************************************************************************/
/* USER CODE END Header */
#include "app_rtc.h"static time_t g_rtc_cur_stamp = 0;static bool rtc2tm(et_rtc_t *p_rtc, struct tm *p_tm, bool r2t)
{if (r2t){p_tm->tm_year = 2000 + p_rtc->year - 1900;p_tm->tm_mon = p_rtc->month - 1;p_tm->tm_mday = p_rtc->day;p_tm->tm_hour = p_rtc->hour;p_tm->tm_min = p_rtc->minute;p_tm->tm_sec = p_rtc->second;}else{p_rtc->year = p_tm->tm_year + 1900 - 2000;p_rtc->month = p_tm->tm_mon + 1;p_rtc->day = p_tm->tm_mday;p_rtc->hour = p_tm->tm_hour;p_rtc->minute = p_tm->tm_min;p_rtc->second = p_tm->tm_sec;}return (p_tm->tm_year >= 2024 - 1900) &&(p_tm->tm_mon >= 0) && (p_tm->tm_mon <= 11) &&(p_tm->tm_mday >= 1) && (p_tm->tm_mday <= 31) &&(p_tm->tm_hour >= 0) && (p_tm->tm_hour <= 23) &&(p_tm->tm_min >= 0) && (p_tm->tm_min <= 59) &&(p_tm->tm_sec >= 0) && (p_tm->tm_sec <= 59);
}void rtc_expiry_function_callback(void )
{g_rtc_cur_stamp += 1;app_rtc_test();
}void app_rtc_set( et_rtc_t *prtc)
{struct tm t;rtc2tm(prtc, &t, true); drv_grtc_stop();    g_rtc_cur_stamp = mktime(&t); drv_grtc_start();
}void app_rtc_get( et_rtc_t *p_rtc,  time_t *stamp)
{struct tm t;*stamp = g_rtc_cur_stamp;t = *localtime(stamp);rtc2tm(p_rtc, &t, false);
}void app_init_rtc( void )
{et_rtc_t rtc;build_rtc( &rtc );drv_grtc_init();app_rtc_set( &rtc );
}void app_rtc_test( void )
{time_t stamp;et_rtc_t rtc;app_rtc_get((et_rtc_t *)&rtc, &stamp);printk("rtc(%02d/%02d/%02d %02d:%02d:%02d)",rtc.year, rtc.month, rtc.day,rtc.hour, rtc.minute, rtc.second);    
}void app_rtc_first_set( void )
{et_rtc_t _rtcObj;build_rtc( &_rtcObj );app_rtc_set( &_rtcObj );    
}/** End of this file  */

验证数据:

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

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

相关文章

基于BEKK-GARCH模型的参数估计、最大似然估计以及参数标准误估计的MATLAB实现

基于BEKK-GARCH模型的参数估计、最大似然估计以及参数标准误估计的MATLAB实现。BEKK-GARCH模型是一种多变量GARCH模型&#xff0c;用于估计多个时间序列的条件方差和协方差矩阵。 MATLAB实现BEKK-GARCH模型 1. 准备数据 假设你已经有一个时间序列数据矩阵 returns&#xff0c;每…

TDengine 中 TDgpt 用于异常检测

介绍 TDgpt 内置时序数据异常检测模型 TDengine 中定义了异常&#xff08;状态&#xff09;窗口来提供异常检测服务。异常窗口可以视为一种特殊的事件窗口&#xff08;Event Window&#xff09;&#xff0c;即异常检测算法确定的连续异常时间序列数据所在的时间窗口。与普通事件…

统计学08:概率分布

一、随机变量随机变量是一个将 随机事件 映射到 数值 的数学函数&#xff0c;用于描述事件的结果。随机变量可以是离散的&#xff08;如骰子&#xff09;或连续的&#xff08;如人的身高、体重&#xff09;。1&#xff09;概率质量函数PMF——离散随机变量P(X x) 对应于某个值…

vue3【组件封装】消息反馈 S-msgWin.vue (针对父容器对齐,左右居中,可自定义顶部距离)

最终效果成功的提示报错的提示代码实现components/SUI/S-msgWin.vue <script lang"ts" setup> const props defineProps({msg: {type: Object,required: true,},top: {type: String,default: "50%",},duration: {type: Number,default: 3000,}, });…

MySQL 8.0.42创建MGR集群

MySQL 8.0.42创建MGR集群 概述 关于MySQL MGR集群的介绍就不在这里做详细的介绍了&#xff0c;大家可以自己到官网上查看阅读。在这里主要是实际操作方面的内容 总体结构设计如下图服务器节点信息序号角色IP地址数据库端口MGR端口1主节点192.168.56.1043309100612从节点192.168…

《Go Web编程实战派--从入门到精通》的随笔笔记

第二章 Go Web 开发基础2.1第一个Go Web 程序package mainimport ("fmt""net/http" )func hello(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello World") } func main() {server : &http.Server{Addr: "0.0.0.0:80&q…

MySQL在Linux环境下的性能调优

&#x1f4ca; MySQL性能基准测试&#xff1a;知己知彼建立性能基线的关键指标# 核心性能指标监控脚本 #!/bin/bash echo " MySQL Performance Baseline " mysql -e "SHOW GLOBAL STATUS LIKE Questions;" mysql -e "SHOW GLOBAL STATUS LIKE Uptime;…

PyQt事件处理机制深度指南:超越信号与槽的底层掌控

—— 5大核心策略实战案例&#xff0c;解锁GUI交互的底层密码 &#x1f50d; 事件与信号槽的本质差异维度事件处理机制信号与槽机制抽象层级操作系统消息的原始封装对事件的高级封装应用场景控件行为定制/底层交互常规业务逻辑绑定执行顺序先于信号槽触发在事件处理完成后触发性…

10_opencv_分离颜色通道、多通道图像混合

split() 通道分离 void cv::split(const Mat & src,Mat * mvbegin ) merge() 通道合并 void cv::merge(InputArrayOfArrays mv,OutputArray dst ) Mat::at()方法 Mat::at()方法返回一个引用到指定的数组元素。 注意是引用&#xff0c;相当于两者等价&#xff0c;也就是…

Kotlin的datetime库

kotlinx 是一组不是 Kotlin 标准库一部分&#xff0c;但非常实用的扩展项目集合。其中&#xff0c;kotlinx-datetime 是一个跨平台的 Kotlin 时间日期处理库。 如何在项目中使用该库 Gradle 项目中 在 repositories 块中添加 Maven Central 仓库&#xff1a; repositories {…

基于模型蒸馏的大模型文案生成最佳实践

背景 大语言模型在生成高质量文案方面表现优异&#xff0c;然而其巨大的计算资源消耗和存储需求&#xff0c;使得实际应用尤其是在资源受限场景中的应用充满挑战。企业在寻求高效的文案生成时&#xff0c;常常面临着在性能和资源之间权衡的困境。在这种背景下&#xff0c;模型…

调用通义千问大模型实现流式对话

前言 我使用的是硅基流动中通义千问免费的大模型&#xff1a;我的技术栈使用的 Next14.2 全栈框架。 代码结构 需要使用的库&#xff1a; npm i ai openai目录结构&#xff1a; 基础测试页面 test-openai/page.tsx&#xff1a; use client;import { useChat } from ai/react;ex…

如何搭建Linux环境下的flink本地集群

第一步&#xff0c;搭建Linux环境 这里我使用的是 WSL2 安装前&#xff0c;先用管理员打开终端&#xff0c;执行以下三条命令&#xff0c;目的是开启安装 WSL2所需要的环境 //开启适用于windows的Linux子系统 dism.exe /online /enable-feature /featurename:Microsoft-Wind…

算法:链表part02:24. 两两交换链表中的节点 + 19. 删除链表的倒数第 N 个结点 + 面试题 02.07. 链表相交

24. 两两交换链表中的节点题目&#xff1a;https://leetcode.cn/problems/swap-nodes-in-pairs/description/ 讲解&#xff1a;https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html 复习可以先…

【Linux学习】(11)进程的概念

前言在上一章我们知道了什么是进程&#xff0c;并简单了解了PCB。 本文我们将继续深入学习进程概念相关知识点&#xff1a; 学习进程状态&#xff0c;学会创建进程&#xff0c;掌握僵尸进程和孤儿进程&#xff0c;及其形成原因和危害了解进程调度&#xff0c;Linux进程优先级&a…

UniappDay04

1.登录模块-小程序快捷登录定义接口&#xff0c;封装 import { http } from /utils/httptype loginParams {code: stringencryptedData: stringiv: string } export const postLoginWxMinAPI (data: loginParams) > {return http({method: POST,url: /login/wxMin,data,})…

NPM/Yarn完全指南:前端开发的“基石“与“加速器“

开篇:当你第一次运行npm install时... "这node_modules文件夹怎么比我的项目代码还大100倍?!" —— 每个前端新手第一次看到node_modules时的反应都出奇地一致。别担心,今天我要带你彻底搞懂这个让项目"膨胀"的"罪魁祸首",以及如何用NPM/Y…

vue页面自定义滚动条

效果图实现思路 固定整个灰色滚动条的长度计算可滚动区域占整个可视视图的比例&#xff0c;来确定橙色块的长度监听页面滚动&#xff0c;计算橙色块向右偏移距离 主要代码 template&#xff1a; <div v-show"showBar" ref"barRef" class"scrollbar…

企业级JWT验证最佳方案:StringUtils.hasText()

在企业级Java开发中&#xff0c;判断JWT令牌是否有效的最全面且常用的方式是结合以下两种方法&#xff1a; ✅ 推荐方案&#xff1a;StringUtils.hasText(jwt)&#xff08;Spring框架&#xff09; import org.springframework.util.StringUtils;if (!StringUtils.hasText(jwt))…

灵动画布:快手可灵 AI 推出的多人协作 AI 创意工作台

灵动画布&#xff1a;快手可灵 AI 推出的多人协作 AI 创意工作台 来源&#xff1a;Poixe AI 一、什么是灵动画布 灵动画布是快手旗下可灵 AI 于 2025 世界人工智能大会期间发布的全新创意工作台功能。该功能集无限可视化画布空间、多人实时协作及 AI 智能辅助于一体&#xf…