C語言編程中的時間處理

最簡單的time

在C語言編程中,處理時間最簡單的函數就是time了。它的原型為:

#include <time.h>  time_t time(time_t *_Nullable tloc);

返回自從EPOCH,即1970年1月1日的零點零時零分,到當前的秒數。

輸入參數可以是NULL。如果輸入參數不是NULL,那么返回值也會存入tloc的地址處。

需要注意的是,在不同的平臺上,這里的time_t定義可能不同。

glibc-devel-2.41中,/usr/include/bits/types/time_t.h中有如下定義:

 #include <bits/types.h>5 6 /* Returned by `time'.  */7 #ifdef __USE_TIME64_REDIRECTS8 typedef __time64_t time_t;9 #else10 typedef __time_t time_t;11 #endif

__time64_t__time_t的定義則如下:

__STD_TYPE __TIME64_T_TYPE __time64_t;__STD_TYPE __TIME_T_TYPE __time_t;      /* Seconds since the Epoch.  */

再繼續跟下去,涉及到各種宏等分支,最終的定義在Fedora 42的X86_64平臺上,這個值是long int。

Linux中的gettimeofday/settimeofday

time簡單,但是也粗糙,它只能取到秒這個單位。而gettimeofday則可能取到微秒。

與之相對,settimeofday則可以設置系統時間。

gettimeofday/settimeofday的原型如下:

       #include <sys/time.h>int gettimeofday(struct timeval *restrict tv,struct timezone *_Nullable restrict tz);int settimeofday(const struct timeval *tv,const struct timezone *_Nullable tz);

struct timeval的定義為:

          struct timeval {  time_t      tv_sec;     /* seconds */  suseconds_t tv_usec;    /* microseconds */  };

tv_sec就是秒數,tv_usec是微秒。

struct timezone的定義為:

          struct timezone {  int tz_minuteswest;     /* minutes west of Greenwich */  int tz_dsttime;         /* type of DST correction */  };

當執行gettimeofday之后,返回0表示成功,非0表示失敗。

需要注意的是,tz這個結構已經過時,在我們使用gettimeofday與settimeofday的時候,直接把tz設為NULL,取得或者設置當前的本地時間就好了。

Windows中的GetLocalTime/SetLocalTime

在Windows環境下,取得與設置時間,可以使用GetLocalTime與SetLocalTime函數。

這兩個函數的原型如下:

void GetLocalTime([out] LPSYSTEMTIME lpSystemTime
);BOOL SetLocalTime([in] const SYSTEMTIME *lpSystemTime
);

相關的數據結構定義如下:

typedef struct _SYSTEMTIME {WORD wYear;WORD wMonth;WORD wDayOfWeek;WORD wDay;WORD wHour;WORD wMinute;WORD wSecond;WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

其中:
wYear

年數,范圍是從1601到30872。

mMonth

月數,范圍是從1到12。

mDayOfWeek

周偏移數,范圍是從0到6。

wDay

天數,范圍是從 1 到 31。

wHour

小時數,范圍是從 0 到 23。

wMinute

分鐘數,范圍是從 0 到 59。

wSecond

秒數,范圍是從 0 到 59。

wMilliseconds

毫秒數,范圍是從 0 到 999。

還需要注意,SetLocalTime的返回值是布爾值,成功為非0。

以下代碼,把一個從Linux取得的timeval時間,轉化成Windows上的時間,進行設置:

int set_local_time_by_timeval (const struct timeval *tv)
{struct tm utc_tm;SYSTEMTIME st = { 0 };   if (localtime_s (&utc_tm, &tv->tv_sec) != 0)  {    return -1;}  st.wYear = utc_tm.tm_year + 1900;  st.wMonth = utc_tm.tm_mon + 1;  st.wDay = utc_tm.tm_mday;  st.wHour = utc_tm.tm_hour;  st.wMinute = utc_tm.tm_min;  st.wSecond = utc_tm.tm_sec;  st.wMilliseconds = (WORD)(time % (1000 * 1000) / 1000);  return SetLocalTime (&st) ? 0 : -1;

glib里的g_get_monotonic_time

如果我們的項目使用了glib(注意是glib,不是glibc),還有一個方便的函數可以使用,那就是g_get_monotonic_time

這個函數表示系統啟動以來經過的微秒數,用來做一些時間間隔設計等工作。

比如,我們需要開發一些timer類功能,在程序經過若干時間之后,執行什么操作,如果使用time或者gettimeofday之類的函數,在系統時間改變之后,就會錯亂。

但是,如果我們使用g_get_monotonic_time則可以完全避免這種問題。

如:

gint64 start = g_get_monotonic_time();/* 此處是需要測量的業務代碼 */
/* 而且有可能系統時間更改 */gint64 end = g_get_monotonic_time();
g_print("耗時: %" G_GINT64_FORMAT " 微秒\n", end - start);

glib的這個函數有點像C++中的std::chrono::steady_clock

底層的clock_gettime

如果進行更精確地時間控制,在Linux中還可以使用clock族的幾個函數:

    #include <time.h>  int clock_getres(clockid_t clockid, struct timespec *_Nullable res);  int clock_gettime(clockid_t clockid, struct timespec *tp);  int clock_settime(clockid_t clockid, const struct timespec *tp);

其中,clockid是可以控制的一些參數,如CLOCK_MONOTONIC、CLOCK_BOOTTIME、CLOCK_REALTIME等,具體意義可以見文知義。

而timespec的定義類似于timeval,但是第二個參數不是微秒,而是納秒。

      #include <time.h>  struct timespec {  time_t     tv_sec;   /* Seconds */  /* ... */   tv_nsec;  /* Nanoseconds [0, 999'999'999] */  };

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83411.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

適應性神經樹:當深度學習遇上決策樹的“生長法則”

1st author: Ryutaro Tanno video: Video from London ML meetup paper: Adaptive Neural Trees ICML 2019 code: rtanno21609/AdaptiveNeuralTrees: Adaptive Neural Trees 背景 在機器學習領域&#xff0c;神經網絡&#xff08;NNs&#xff09;憑借其強大的表示學習能力&…

InitVerse節點部署教程

項目介紹: InitVerse 是一個為新興企業量身定制的自動化 Web3 SaaS 平臺,只需單擊幾下即可快速開發和部署 DApp。在 INIChain 和 INICloud 的支持下,InitVerse 可以根據需求動態調整計算資源,實現高效的任務處理,同時提供更高的安全性、可用性和可擴展性。 系統要求: C…

阿里開源通義萬相 Wan2.1-VACE,開啟視頻創作新時代

0.前言 阿里巴巴于2025年5月14日正式開源了其最新的AI視頻生成與編輯模型——通義萬相Wan2.1-VACE。這一模型是業界功能最全面的視頻生成與編輯工具&#xff0c;能夠同時支持多種視頻生成和編輯任務&#xff0c;包括文生視頻、圖像參考視頻生成、視頻重繪、局部編輯、背景延展…

解決“VMware另一個程序已鎖定文件的一部分,進程無法訪問“

問題描述 打開VMware里的虛擬機時&#xff0c;彈出"另一個程序已鎖定文件的一部分&#xff0c;進程無法訪問"如圖所示&#xff1a; 這是VM虛擬機的保護機制。虛擬機運行時&#xff0c;為防止數據被篡改&#xff0c;會將所運行的文件保護起來。當虛擬機崩潰或者強制…

基于大數據的租房信息可視化系統的設計與實現【源碼+文檔+部署】

課題名稱 基于大數據的租房信息可視化系統的設計與實現 學 院 專 業 計算機科學與技術 學生姓名 指導教師 一、課題來源及意義 租房市場一直是社會關注的熱點問題。隨著城市化進程的加速&#xff0c;大量人口涌入城市&#xff0c;導致租房需求激增。傳統的租…

Vue3封裝公共圖片組件

對圖片加載做的處理: 圖片加載狀態響應式管理圖片訪問錯誤的處理機制圖片懶加載可通過slot支持自定義加載動畫其他監聽事件的處理及向上傳遞 …<!-- components/CustomImage.vue --> <template><div class="custom-image-wrapper"><!-- 主圖 -…

車道線檢測----CLRKDNet

今天的最后一篇 車道線檢測系列結束 CLRKDNet&#xff1a;通過知識蒸餾加速車道檢測 摘要&#xff1a;道路車道是智能車輛視覺感知系統的重要組成部分&#xff0c;在安全導航中發揮著關鍵作用。在車道檢測任務中&#xff0c;平衡精度與實時性能至關重要&#xff0c;但現有方法…

Python-感知機以及實現感知機

感知機定義 如果有一個算法&#xff0c;具有1個或者多個入參&#xff0c;但是返回值要么是0&#xff0c;要么是1&#xff0c;那么這個算法就叫做感知機&#xff0c;也就是說&#xff0c;感知機是個算法 感知機有什么用 感知機是用來表示可能性的大小的&#xff0c;我們可以認…

STM32 ADC+DMA+TIM觸發采樣實戰:避坑指南與源碼解析

知識點1【TRGO的介紹】 1、TRGO的概述 TRGO&#xff1a;Trigger Output&#xff08;觸發輸出&#xff09;&#xff0c;是定時器的一種功能。 它可以作為外設的啟動信號&#xff0c;比如ADC轉換&#xff0c;DAC輸出&#xff0c;DMA請求等。 對于ADC來說&#xff0c;可以通過…

Qwen3技術報告解讀

https://github.com/QwenLM/Qwen3/blob/main/Qwen3_Technical_Report.pdf 節前放模型&#xff0c;大晚上的發技術報告。通義&#xff0c;真有你的~ 文章目錄 預訓練后訓練Long-CoT Cold StartReasoning RLThinking Mode FusionGeneral RLStrong-to-Weak Distillation 模型結構…

【網絡編程】十、詳解 UDP 協議

文章目錄 Ⅰ. 傳輸層概述1、進程之間的通信2、再談端口號端口號的引出五元組標識一個通信端口號范圍劃分常見的知名端口號查看知名端口號協議號 VS 端口號 3、兩個問題一個端口號是否可以被多個進程綁定&#xff1f;一個進程是否可以綁定多個端口號&#xff1f; 4、部分常見指令…

實現RTSP低延遲播放器,挑戰與解決方案

隨著低延遲直播需求的快速增長&#xff0c;RTSP&#xff08;Real-Time Streaming Protocol&#xff09;播放器逐漸成為實時視頻流傳輸中的核心技術之一。與WebRTC&#xff08;Web Real-Time Communication&#xff09;相比&#xff0c;RTSP在實時性和網絡延遲方面面臨諸多挑戰&…

【springcloud學習(dalston.sr1)】Eureka單個服務端的搭建(含源代碼)(三)

該系列項目整體介紹及源代碼請參照前面寫的一篇文章【springcloud學習(dalston.sr1)】項目整體介紹&#xff08;含源代碼&#xff09;&#xff08;一&#xff09; springcloud學習&#xff08;dalston.sr1&#xff09;系統文章匯總如下&#xff1a; 【springcloud學習(dalston…

GPU與NPU異構計算任務劃分算法研究:基于強化學習的Transformer負載均衡實踐

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;H卡級別算力&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生專屬優惠。 引言 在邊緣計算與AI推理場景中&#xff0c;GPU-NPU異構計算架構已成為突破算力瓶頸的關鍵技…

探索C語言中的二叉樹:原理、實現與應用

一、引言 二叉樹作為一種重要的數據結構&#xff0c;在計算機科學領域有著廣泛的應用&#xff0c;無論是在操作系統的文件系統管理&#xff0c;還是在數據庫的索引構建中&#xff0c;都能看到它的身影。在C語言中&#xff0c;我們可以利用指針靈活地構建和操作二叉樹。接下來&…

使用libUSB-win32的簡單讀寫例程參考

USB上位機程序的編寫&#xff0c;函數的調用過程. 調用 void usb_init(void); 進行初始化 調用usb_find_busses、usb_find_devices和usb_get_busses這三個函數&#xff0c;獲得已找到的USB總線序列&#xff1b;然后通過鏈表遍歷所有的USB設備&#xff0c;根據已知的要打開USB設…

vue注冊用戶使用v-model實現數據雙向綁定

定義數據模型 Login.vue //定義數據模型 const registerData ref({username: ,password: ,confirmPassword: })使用 v-model 實現數據模型的key與注冊表單中的元素之間的雙向綁定 <!-- 注冊表單 --><el-form ref"form" size"large" autocompl…

【Arthas實戰】常見使用場景與命令分享

簡介: Arthas是一款Java診斷工具&#xff0c;適用于多種場景&#xff0c;如接口響應變慢、CPU占用過高、熱更新需求等。其核心命令包括實時監控面板&#xff08;dashboard&#xff09;、線程狀態查看&#xff08;thread&#xff09;、方法調用鏈路追蹤&#xff08;trace&#x…

Jenkins 最佳實踐

1. 在Jenkins中避免調度過載 過載Jenkins以同時運行多個作業可能導致資源競爭、構建速度變慢和系統性能問題。分配作業啟動時間可以防止瓶頸&#xff0c;并確保更順暢的執行。如何實現&#xff1f; 在Cron表達式中使用H&#xff1a;引入抖動&#xff08;jitter&#xff09;&a…

pytest框架 - 第二集 allure報告

一、斷言assert 二、Pytest 結合 allure-pytest 插件生成美觀的 Allure 報告 (1) 安裝 allure 環境 安裝 allure-pytest 插件&#xff1a;pip install allure-pytest在 github 下載 allure 報告文件 地址&#xff1a;Releases allure-framework/allure2 GitHub下載&#x…