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. 非線程安全性

    • gmtime,?localtime,?asctime,?ctime?使用靜態緩沖區

    • 多線程環境中應使用?_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
英文地址,請注明出處:http://en.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…