
C语言 time.h 头文件详解一、头文件详解1. 引言2. 核心类型2.1 time_t2.2 struct tm2.3 clock_t3. 常用函数3.1 time() — 获取当前时间3.2 localtime() 与 gmtime() — 时间转换3.3 strftime() — 格式化时间输出3.4 mktime() — 将 struct tm 转回 time_t3.5 difftime() — 计算时间差3.6 clock() — 测量处理器时间3.7 asctime() 与 ctime() — 简单字符串输出4. 综合示例完整的日期时间工具5. 注意事项6. 总结二、代码示例一、头文件详解1. 引言在 C 语言的标准库中time.h头文件提供了处理日期和时间的函数与类型。无论是记录程序运行耗时、生成时间戳还是格式化输出当前时间time.h都是开发者不可或缺的工具。本文将系统讲解time.h中的核心类型、常用函数以及实际应用示例帮助你彻底掌握 C 语言中的时间处理。2. 核心类型time.h中定义了若干与时间相关的数据类型理解它们是使用时间函数的前提。2.1time_ttime_t是一个算术类型通常是long或long long用于表示从 1970 年 1 月 1 日 00:00:00 UTCUnix 纪元起经过的秒数。它是最基础的时间表示形式。#includetime.htime_tnow;nowtime(NULL);// 获取当前时间秒数2.2struct tmstruct tm是一个结构体将时间拆分为年、月、日、时、分、秒等可读字段便于程序直接访问。structtm{inttm_sec;// 秒0-59inttm_min;// 分0-59inttm_hour;// 时0-23inttm_mday;// 日1-31inttm_mon;// 月0-110 表示一月inttm_year;// 年自 1900 起的年数inttm_wday;// 星期0-60 表示星期日inttm_yday;// 一年中的第几天0-365inttm_isdst;// 夏令时标志};注意tm_mon从 0 开始tm_year从 1900 开始使用时需要相应调整。2.3clock_tclock_t用于表示处理器时钟计时单元clock ticks通常配合clock()函数测量程序运行时间。3. 常用函数3.1time()— 获取当前时间time_ttime(time_t*timer);返回当前日历时间秒数。若timer不为NULL也会将结果写入该指针指向的变量。time_tnowtime(NULL);printf(当前时间戳%ld\n,(long)now);3.2localtime()与gmtime()— 时间转换structtm*localtime(consttime_t*timer);// 转换为本地时间structtm*gmtime(consttime_t*timer);// 转换为 UTC 时间两者都返回指向静态struct tm的指针因此多次调用会覆盖同一块内存。time_tnowtime(NULL);structtm*locallocaltime(now);printf(本地时间%d-%02d-%02d %02d:%02d:%02d\n,local-tm_year1900,local-tm_mon1,local-tm_mday,local-tm_hour,local-tm_min,local-tm_sec);3.3strftime()— 格式化时间输出size_tstrftime(char*str,size_tmaxsize,constchar*format,conststructtm*timeptr);按照指定格式将struct tm格式化为字符串是输出时间最灵活的方式。time_tnowtime(NULL);structtm*locallocaltime(now);charbuffer[64];strftime(buffer,sizeof(buffer),%Y-%m-%d %H:%M:%S,local);printf(格式化时间%s\n,buffer);常用格式说明符格式符含义示例%Y四位年份2026%m两位月份01-1209%d两位日期01-3123%H24 小时制小时00-2311%M分钟00-5958%S秒00-5927%A星期全名Wednesday%B月份全名September3.4mktime()— 将struct tm转回time_ttime_tmktime(structtm*timeptr);将本地时间表示的struct tm转换为time_t秒数同时会规范化字段如将tm_mon溢出自动进位。structtmt{0};t.tm_year2026-1900;// 年份从 1900 起算t.tm_mon8;// 9 月0 起算t.tm_mday23;time_ttsmktime(t);printf(对应时间戳%ld\n,(long)ts);3.5difftime()— 计算时间差doubledifftime(time_ttime1,time_ttime0);返回time1 - time0的秒数差返回类型为double。time_tstarttime(NULL);// 模拟耗时操作for(volatileinti0;i100000000;i);time_tendtime(NULL);printf(耗时%.2f 秒\n,difftime(end,start));3.6clock()— 测量处理器时间clock_tclock(void);返回程序自启动以来消耗的处理器时钟数除以CLOCKS_PER_SEC得到秒数。clock_tstartclock();// 模拟耗时操作for(volatileinti0;i100000000;i);clock_tendclock();printf(CPU 耗时%.3f 秒\n,(double)(end-start)/CLOCKS_PER_SEC);3.7asctime()与ctime()— 简单字符串输出char*asctime(conststructtm*timeptr);char*ctime(consttime_t*timer);两者都返回固定格式的字符串如Wed Sep 23 11:58:27 2026但包含换行符且线程不安全建议优先使用strftime()。time_tnowtime(NULL);printf(ctime 输出%s,ctime(now));4. 综合示例完整的日期时间工具下面是一个综合示例演示如何获取当前时间、格式化输出、计算时间差以及将字符串解析为时间戳。#includestdio.h#includetime.hintmain(){// 1. 获取当前时间time_tnowtime(NULL);printf(当前时间戳%ld\n,(long)now);// 2. 转换为本地时间并格式化输出structtm*locallocaltime(now);charbuffer[64];strftime(buffer,sizeof(buffer),%Y-%m-%d %H:%M:%S %A,local);printf(本地时间%s\n,buffer);// 3. 计算两个时间点之间的差值structtmt1{0},t2{0};t1.tm_year2026-1900;t1.tm_mon8;t1.tm_mday23;t2.tm_year2026-1900;t2.tm_mon8;t2.tm_mday24;time_tts1mktime(t1);time_tts2mktime(t2);printf(两天相差%.0f 秒\n,difftime(ts2,ts1));// 4. 测量代码段执行时间clock_tstartclock();for(volatileinti0;i50000000;i);clock_tendclock();printf(循环耗时%.3f 秒\n,(double)(end-start)/CLOCKS_PER_SEC);return0;}5. 注意事项线程安全localtime()、gmtime()、asctime()、ctime()返回静态内存多线程环境下应使用localtime_r()、gmtime_r()等可重入版本。时区处理localtime()依赖系统时区设置跨时区应用需谨慎。精度限制time_t以秒为单位高精度计时应使用time.h的clock_gettime()POSIX或 C11 的timespec_get。年份范围struct tm的tm_year从 1900 起算32 位time_t在 2038 年可能溢出64 位系统通常无此问题。6. 总结time.h提供了从底层时间戳到高层格式化输出的完整时间处理能力。掌握time_t、struct tm两种核心类型以及time()、localtime()、strftime()、mktime()、difftime()、clock()等常用函数就能应对绝大多数 C 语言时间编程需求。建议在实际项目中优先使用strftime()进行格式化输出并注意线程安全与精度问题。二、代码示例#define_CRT_SECURE_NO_WARNINGS#includestdio.h#includetime.h#includeWindows.hintmain(void){SetConsoleOutputCP(CP_UTF8);// 1. time_tUnix时间戳从1970-01-01 00:00:00 UTC 开始的秒数time_tnow_ts;time(now_ts);// 获取当前系统时间戳等价 now_ts time(NULL);printf(1. 当前Unix时间戳(秒) %lld\n\n,(longlong)now_ts);// 2. localtime()时间戳 →【本地时区】struct tm年月日时分秒structtm*local_tm_ptrlocaltime(now_ts);printf(2. localtime 本地时间:\n);printf( 年:%d,月:%d,日:%d 时:%d:%d:%d\n,local_tm_ptr-tm_year1900,// tm_year 年份-1900local_tm_ptr-tm_mon1,// tm_mon:0~11 → 1local_tm_ptr-tm_mday,local_tm_ptr-tm_hour,local_tm_ptr-tm_min,local_tm_ptr-tm_sec);printf( 星期 tm_wday(0周日):%d年内第%d天\n\n,local_tm_ptr-tm_wday,local_tm_ptr-tm_yday);// 3. gmtime()时间戳 →【UTC零时区】struct tmstructtm*utc_tm_ptrgmtime(now_ts);printf(3. gmtime UTC零时区时间:\n);printf( 年:%d,月:%d,日:%d 时:%d:%d:%d\n\n,utc_tm_ptr-tm_year1900,utc_tm_ptr-tm_mon1,utc_tm_ptr-tm_mday,utc_tm_ptr-tm_hour,utc_tm_ptr-tm_min,utc_tm_ptr-tm_sec);// 4. strftime() 格式化时间字符串重点前面RTDateTime用到charbuf[64];strftime(buf,sizeof(buf),%Y-%m-%d %H:%M:%S,local_tm_ptr);printf(4. strftime格式化本地时间字符串%s\n\n,buf);// 5. mktime()struct tm → time_t反向转换年月日转时间戳structtmcustom_tm{0};custom_tm.tm_year2026-1900;custom_tm.tm_mon9-1;//9月custom_tm.tm_mday23;custom_tm.tm_hour10;custom_tm.tm_min0;custom_tm.tm_sec0;time_tcustom_tsmktime(custom_tm);printf(5. mktime2026-09-23 10:00:00 对应的时间戳 %lld\n\n,(longlong)custom_ts);// 6. difftime()计算两个time_t之间相差多少秒返回doubletime_tt1time(NULL);// 模拟延时VS用Sleeplinux用sleep// Sleep(1000);time_tt2time(NULL);doublediff_secdifftime(t2,t1);printf(6. difftime 时间差%.3f 秒\n\n,diff_sec);// 【重要】线程安全版本演示 // VS: localtime_s(tm_safe, now_ts);// RT-Thread/Linux: localtime_r(now_ts, tm_safe);structtmtm_safe;#ifdef_WIN32localtime_s(tm_safe,now_ts);#elselocaltime_r(now_ts,tm_safe);#endifstrftime(buf,sizeof(buf),%Y-%m-%d %H:%M:%S,tm_safe);printf(7. 可重入安全版本 localtime_s/r%s\n,buf);return0;}