linux c++ 獲取時間,詳解Linux下的C++時間類型:time_t

Unix時間戳(Unix timestamp),或稱Unix時間(Unix time)、POSIX時間(POSIX

time),是一種時間表示方式,定義為從格林威治時間1970年01月01日00時00分00秒起至現在的總秒數。Unix時間戳不僅被使用在Unix

系統、類Unix系統中,也在許多其他操作系統中被廣泛采用。

目前相當一部分操作系統使用32位二進制數字表示時間。此類系統的Unix時間戳最多可以使用到格林威治時間2038年01月19日03時14分07秒(二進制:01111111

11111111 11111111 11111111)。其后一秒,二進制數字會變為10000000 00000000 00000000

00000000,發生溢出錯誤,造成系統將時間誤解為1901年12月13日20時45分52秒。這很可能會引起軟件故障,甚至是系統癱瘓。使用64位二進制數字表示時間的系統(最多可以使用到格林威治時間292,277,026,596年12月04日15時30分08秒)則基本不會遇到這類溢出問題。

首先課課家視頻教程平臺帶大家了解一下時間的相關概念,以及之間的區別,需要了解的時間概念有:

本地時間(locale time)

格林威治時間(Greenwich Mean Time GMT)

時間協調時間 (Universal Time Coordinated UTC)

本地時間,顯而易見不用解釋了

先看看時間的標準:

(1)世界時

世界時是最早的時間標準。在1884年,國際上將1s確定為全年內每日平均長度的1/8.64×104。以此標準形成的時間系統,稱為世界是,即UT1。1972年國際上開始使用國際原子時標,從那以后,經過格林威治老天文臺本初子午線的時間便被稱為世界時,即UT2,或稱格林威治時間(GMT),是對地球轉速周期性差異進行校正后的世界時。

(2)原子時

1967年,人們利用銫原子振蕩周期極為規律的特性,研制出了高精度的原子時鐘,將銫原子能級躍遷輻射9192631770周所經歷的時間定為1s。現在用的時間就是1971年10月定義的國際原子時,是通過世界上大約200多臺原子鐘進行對比后,再由國際度量衡局時間所進行數據處理,得出的統一的原子時,簡稱TAI。

(3)世界協調時

世界協調時是以地球自轉為基礎的時間標準。由于地球自轉速度并不均勻,并非每天都是精確的86400原子s,因而導致了自轉時間與世界時之間存在18個月有1s的誤差。為糾正這種誤差,國際地球自轉研究所根據地球自轉的實際情況對格林威治時間進行增減閏s的調整,與國際度量衡局時間所聯合向全世界發布標準時間,這就是所謂的世界協調時(UTC:CoordinatdeUniversalTime)。UTC的表示方式為:年(y)、月(m)、日(d)、時(h)、分(min)、秒(s),均用數字表示。

GPS

系統中有兩種時間區分,一為UTC,另一為LT(地方時)兩者的區別為時區不同,UTC就是0時區的時間,地方時為本地時間,如北京為早上八點(東八區),UTC時間就為零點,時間比北京時晚八小時,以此計算即可

通過上面的了解,我們可以認為格林威治時間就是時間協調時間(GMT=UTC),格林威治時間和UTC時間均用秒數來計算的。

而在我們平時工作當中看到的計算機日志里面寫的時間大多數是用UTC時間來計算的,那么我們該怎么將UTC時間轉化為本地時間便于查看日志,那么在作程序開發時又該怎么將本地時間轉化為UTC時間呢?

下面就介紹一個簡單而使用的工具,就是使用Linux/unix命令date來進行本地時間和local時間的轉化。

大家都知道,在計算機中看到的utc時間都是從(1970年01月01日

0:00:00)開始計算秒數的。所看到的UTC時間那就是從1970年這個時間點起到具體時間共有多少秒。

我們在編程中可能會經常用到時間,比如取得系統的時間(獲取系統的年、月、日、時、分、秒,星期等),或者是隔一段時間去做某事,那么我們就用到一些時間函數。

linux下存儲時間常見的有兩種存儲方式,一個是從1970年到現在經過了多少秒,一個是用一個結構來分別存儲年月日時分秒的。

time_t 這種類型就是用來存儲從1970年到現在經過了多少秒,要想更精確一點,可以用結構struct

timeval,它精確到微妙。

struct timeval

{

long tv_sec;

long tv_usec;

};

而直接存儲年月日的是一個結構:

struct tm

{

int tm_sec;

int tm_min;

int tm_hour;

int tm_mday;

int tm_mon; 1+p->tm_mon;

int tm_year; 1900+ p->tm_year;

int tm_wday;

int tm_yday;

int tm_isdst;

};

需要特別注意的是,年份是從1900年起至今多少年,而不是直接存儲如2011年,月份從0開始的,0表示一月,星期也是從0開始的,

0表示星期日,1表示星期一。

下面介紹一下我們常用的時間函數:

#include

char *asctime(const struct tm* timeptr);

將結構中的信息轉換為真實世界的時間,以字符串的形式顯示

char *ctime(const time_t *timep);

將timep轉換為真是世界的時間,以字符串顯示,它和asctime不同就在于傳入的參數形式不一樣

double difftime(time_t time1, time_t time2);

返回兩個時間相差的秒數

int gettimeofday(struct timeval *tv, struct timezone *tz);

返回當前距離1970年的秒數和微妙數,后面的tz是時區,一般不用

struct tm* gmtime(const time_t *timep);

將time_t表示的時間轉換為沒有經過時區轉換的UTC時間,是一個struct tm結構指針

stuct tm* localtime(const time_t *timep);

和gmtime類似,但是它是經過時區轉換的時間。

time_t mktime(struct tm* timeptr);

將struct tm 結構的時間轉換為從1970年至今的秒數

time_t time(time_t *t);

取得從1970年1月1日至今的秒數。

上面是簡單的介紹,下面通過實戰來看看這些函數的用法:

#include

int main()

{

time_t timep;

time(&timep);

printf("%s", asctime(gmtime(&timep)));

return 0;

}

編譯并運行:

$gcc -o gettime1 gettime1.c

$./gettime1

Fri Jan 11 17:04:08 2008

下面是直接把time_t類型的轉換為我們常見的格式:

#include

int main()

{

time_t timep;

time(&timep);

printf("%s", ctime(&timep));

return 0;

}

編譯并運行:

$gcc -o gettime2 gettime2.c

$./gettime2

Sat Jan 12 01:25:29 2008

我看了一本書上面說的這兩個例子如果先后執行的話,兩個的結果除了秒上有差別之外(執行程序需要時間),應該是一樣的,可是我這里執行卻發現差了很長時間按,一個是周五,一個是周六,后來我用

date 命令執行了一遍

$date

六 1月 12 01:25:19 CST 2008

我發現date和gettime2比較一致, 我估計可能gettime1并沒有經過時區的轉換,它們是有差別的。

#include

int main()

{

char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri",

"Sat"};

time_t timep;

struct tm *p;

time(&timep);

p = gmtime(&timep);

printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon,

p->tm_mday);

printf("%s %d:%d:%d\\n", wday[p->tm_wday],

p->tm_hour,

p->tm_min, p->tm_sec);

return 0;

}

編譯并運行:

$gcc -o gettime3 gettime3.c

$./gettime3

2008/1/11 Fri 17:42:54

從這個時間結果上來看,它和gettime1保持一致。

#include

int main()

{

char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri",

"Sat"};

time_t timep;

struct tm *p;

time(&timep);

p = localtime(&timep);

printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon,

p->tm_mday);

printf("%s %d:%d:%d\\n", wday[p->tm_wday], p->tm_hour,

p->tm_min, p->tm_sec);

return 0;

}

編譯并運行:

$gcc -o gettime4 gettime4.c

$./gettime4

2008/1/12 Sat 1:49:29

從上面的結果我們可以這樣說:

time, gmtime, asctime 所表示的時間都是UTC時間,只是數據類型不一樣,

而localtime, ctime

所表示的時間都是經過時區轉換后的時間,它和你用系統命令date所表示的CST時間應該保持一致。

#include

int main()

{

time_t timep;

struct tm *p;

time(&timep);

printf("time():%d\\n",timep);

p = localtime(&timep);

timep = mktime(p); //by lizp 錯誤,沒有時區轉換, 將struct tm

結構的時間轉換為從1970年至p的秒數

printf("time()->localtime()->mktime(): %d\\n",

timep);

return 0;

}

編譯并運行:

$gcc -o gettime5 gettime5.c

$./gettime5

time():1200074913

time()->localtime()->mktime(): 1200074913

這里面把UTC時間按轉換為本地時間,然后再把本地時間轉換為UTC時間,它們轉換的結果保持一致。

#include

int main()

{

time_t timep;

struct tm *p;

time(&timep);

printf("time():%d\\n",timep);

p = gmtime(&timep);

timep = mktime(p); //by lizp 錯誤,沒有時區轉換, 將struct tm

結構的時間轉換為從1970年至p的秒數

printf("time()->gmtime()->mktime(): %d\\n", timep);

return 0;

}

編譯并運行:

$gcc -o gettime6 gettime6.c

$./gettime6

time():1200075192

time()->gmtime()->mktime(): 1200046392

從這里面我們可以看出,轉換后時間不一致了,計算一下,整整差了8個小時(

(1200075192-1200046392)/3600 =

8),說明mktime會把本地時間轉換為UTC時間,這里面本來就是UTC時間,于是再弄個時區轉換,結果差了8個小時,用的時候應該注意。

strftime() 函數將時間格式化

我們可以使用strftime()函數將時間格式化為我們想要的格式。它的原型如下:

size_t strftime(

char *strDest,

size_t maxsize,

const char *format,

const struct tm *timeptr

);

我們可以根據format指向字符串中格式命令把timeptr中保存的時間信息放在strDest指向的字符串中,最多向strDest中存放maxsize個字符。該函數返回向strDest指向的字符串中放置的字符數。

函數strftime()的操作有些類似于sprintf():識別以百分號(%)開始的格式命令集合,格式化輸出結果放在一個字符串中。格式化命令說明串

strDest中各種日期和時間信息的確切表示方法。格式串中的其他字符原樣放進串中。格式命令列在下面,它們是區分大小寫的。

%a 星期幾的簡寫

%A 星期幾的全稱

%b 月分的簡寫

%B 月份的全稱

%c 標準的日期的時間串

%C 年份的后兩位數字

%d 十進制表示的每月的第幾天

%D 月/天/年

%e 在兩字符域中,十進制表示的每月的第幾天

%F 年-月-日

%g 年份的后兩位數字,使用基于周的年

%G 年分,使用基于周的年

%h 簡寫的月份名

%H 24小時制的小時

%I 12小時制的小時

%j 十進制表示的每年的第幾天

%m 十進制表示的月份

%M 十時制表示的分鐘數

%n 新行符

%p 本地的AM或PM的等價顯示

%r 12小時的時間

%R 顯示小時和分鐘:hh:mm

%S 十進制的秒數

%t 水平制表符

%T 顯示時分秒:hh:mm:ss

%u 每周的第幾天,星期一為第一天 (值從0到6,星期一為0)

%U 第年的第幾周,把星期日做為第一天(值從0到53)

%V 每年的第幾周,使用基于周的年

%w 十進制表示的星期幾(值從0到6,星期天為0)

%W 每年的第幾周,把星期一做為第一天(值從0到53)

%x 標準的日期串

%X 標準的時間串

%y 不帶世紀的十進制年份(值從0到99)

%Y 帶世紀部分的十制年份

%z,%Z 時區名稱,如果不能得到時區名稱則返回空字符。

%% 百分號

如果想顯示現在是幾點了,并以12小時制顯示,就象下面這段程序:

#include "time.h"

#include "stdio.h"

int main(void)

{

struct tm *ptr;

time_t lt;

char str[80];

lt=time(NULL);

ptr=localtime(

strftime(str,100,"It is now %I %p",ptr);

printf(str);

return 0;

}

其運行結果為:

It is now 4PM

而下面的程序則顯示當前的完整日期:

#include

#include

#include

int main( void )

{

struct tm *newtime;

char tmpbuf[128];

time_t lt1;

time( <1 );

newtime=localtime(<1);

strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year

%Y.\\n", newtime);

printf(tmpbuf);

return 0;

}

以上內容由課課家linux視頻教程平臺提供

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

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

相關文章

程序員的國慶節如何安排,你想好了嗎?

2019獨角獸企業重金招聘Python工程師標準>>> 就要國慶放假了&#xff0c;國慶節是旅游的黃金期&#xff0c;同時也是我們買買買的幸福期&#xff0c;作為一名技術開發&#xff0c;除了要安排假期旅游行程外也不要忘記提升自己&#xff0c;準備好學習計劃&#xff0c…

Print! Print! Print!

print語句可以實現打印--只是對程序員友好的標準輸出流的接口而已。 從技術角度來講&#xff0c;這是把一個或多個對象轉換為其文本表達形式&#xff0c;然后發送給標準輸出或另一個類似文件的流。 更詳細地說&#xff0c;在Python中&#xff0c;打印與文件和流的概念緊密相連。…

C#讓TopMost窗體彈出并置頂層但不獲取當前輸入焦點的終極辦法

為了使程序在彈出窗口時置頂層且不獲取系統輸入焦點&#xff0c;避免影響用戶當前的操作&#xff0c;來電通來電彈屏軟件嘗試過N多種辦法&#xff0c;例如&#xff1a;彈出前保存當前焦點窗口句柄&#xff0c;彈出時因為使用TopMost系統默認將焦點交給了彈出窗口&#xff0c;彈…

微服務實戰(一):微服務架構的優勢與不足

本文講的是微服務實戰&#xff08;一&#xff09;&#xff1a;微服務架構的優勢與不足&#xff0c;【編者的話】本文來自Nginx官方博客&#xff0c;是微服務系列文章的第一篇&#xff0c;主要探討了傳統的單體式應用的不足&#xff0c;以及微服務架構的優勢與挑戰。正如作者所說…

linux創建zip+函數,linux+shell基礎知識

目錄&#xff1a;1.路徑&#xff1a;2.進程&#xff1a;3.清屏和退出當前命令操作&#xff1a;4.ls 參數&#xff1a;5.創建目錄\文件\復制文件&#xff1a;6.查看文件內容&#xff1a;7.linux通配符&#xff1a;8.grep:9.終止命令&#xff1a;10.搜索文件&#xff1a;11.查看網…

關于浮動float屬性和position:absolute屬性的區別

最近返回頭看了很多書籍&#xff0c;一直在糾結float屬性和absolute絕對定位的區別和使用的情況&#xff0c;給大家分享一下自己的心得和體會吧。 1&#xff0c;float屬性 float屬性意義是讓元素拜托獨占一行的霸道總裁&#xff0c;成為一個普普通通的人。比如下面這個例子 如圖…

Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 分析&#xff1a;考慮走第n步時的情況&#xff0c;可以從第n-1個臺階走一步&#xff0c;也可以從…

3dmax linux版本,如何安裝Linux版FLOW-3D及注意事項

如何安裝Linux版FLOW-3D及注意事項安裝Linux版的flow3d流程&#xff1a;1、復制flow3d安裝CD盤中unix文件夾到Linux系統桌面&#xff1b;(或從CD中直接安裝也可以)2、從terminal進入unix文件夾&#xff1b;3、./install或./install_flow3d4、提示是否接受license協議&#xff0…

高級組合技打造“完美” 捆綁后門

0x00 簡介 之前寫過一篇關于客戶端釣魚的文章&#xff1a;《使用powershell Client進行有效釣魚》中&#xff0c;在使用各個Client進行測試的過程中&#xff0c;個人發現CHM文件是最好用的一個&#xff0c;但是其缺點就是會彈黑框&#xff0c;這樣就會讓被攻擊者察覺。那么怎么…

使用友盟分享心得(SSO登陸,不能獲取accesstoken,不能跳轉APPSSO登陸的問題)

在xcode5中plist 文件是默認有 Bundle DisplayName的 而如果工程是在xcode6環境下開發的話。 這時候就會出現友盟無法跳轉微博跟QQSSO的問題。 solution&#xff1a;在plist中加入bundle DisplayName 轉載于:https://www.cnblogs.com/ZippoatiOS/p/4443933.html

linux單線程處理多個請求,redis是單線程的,如何處理并發請求?

疑問&#xff1a;redis是單線程的&#xff0c;如何并發處理多個請求&#xff1f;下面是我個人的理解。答案是&#xff1a;使用操作系統的多進程機制。也就是我們常說的&#xff0c;多路復用API&#xff0c;多路復用API本質上是對操作系統多路復用功能的封裝。什么是操作系統的多…

Cloudera Manager內部結構、功能包括配置文件、目錄位置等

2019獨角獸企業重金招聘Python工程師標準>>> 問題導讀 1.CM的安裝目錄在什么位置&#xff1f; 2.hadoop配置文件在什么位置&#xff1f; 3.Cloudera manager運行所需要的信息存在什么位置&#xff1f; 4.CM結構和功能是什么&#xff1f; 1. 相關目錄 /var/log/cloud…

python 學習筆記(一)

在Windows上安裝Python 首先&#xff0c;從Python的官方網站www.python.org下載最新的2.7.9版本&#xff0c;地址是這個&#xff1a; http://www.python.org/ftp/python/2.7.9/python-2.7.9.msi 然后&#xff0c;運行下載的MSI安裝包&#xff0c;在選擇安裝組件的一步時&#x…

An ffmpeg and SDL Tutorial

http://dranger.com/ffmpeg/轉載于:https://www.cnblogs.com/qwertWZ/p/4447141.html

linux模式匹配,sed的模式匹配用法探討

[rootsunsky Desktop]# cat sunskyabcdef[rootsunsky Desktop]# cat sunsky|sed 1,2d|sed 1,2def[rootsunsky Desktop]# cat sunsky|sed -e 1,2d -e 1,2ddef問題&#xff1a;sed中-e的意思是直接在指令列模式上進行sed的動作編輯按照&#xff0c;那么按照-e的含義&#xff0c;上…

Qualcomm QXDM工具簡介和log抓取

高通工具簡介QXDM 簡介QXDM 安裝QXDM 激活QXDM 使用AT打開Diagnostic口 QXDM 配置1 Message View ConfigurationMessage PacketsLog PacketsLog PacketsOTAEvent ReportsStrings2 Log View Config3 QXDM-保存配置文件4 QXDM-導入配置文件QPST 端口配置QXDM 抓取log QXDM LOG保存…

layout_gravity

layout_gravity——當前View&#xff0c;本身&#xff0c;在父一級的控件所分配的顯示范圍內的&#xff0c;對齊方式常用在&#xff1a; 當前控件&#xff08;在父一級LineLayout所分配給其的顯示范圍內&#xff09;的對齊方式需要注意的是&#xff0c;如果TableRow的gravity確…

Linux_arm_啟動_c語言部分詳解,[原創]Linux arm 啟動 c語言部分詳解第四講

Linux arm啟動c語言部分詳解第四講(from setup_per_cpu_areas();)Written by leeming上面的setup_arch花了我們大量的篇幅&#xff0c;現在我們要繼續往前推進了。注&#xff1a;黑色為主線&#xff0c;藍色為函數的一級展開&#xff0c;紅色是注意重要的地方。//因為我們沒有定…

Kudu1.1.0 、 Kudu1.2.0 Kudu1.3.0的版本信息異同比較

不多說&#xff0c;直接上干貨&#xff01; Kudu1.1.0 新特性 python API升級&#xff0c;具備JAVA Cclient一樣的功能&#xff08;從0.3版本直接升級到1.1&#xff09;&#xff0c;主要的點如下&#xff1a; 1.1. 改進了Parial Row的語義 1.2. 增加了range partition支持 1.3.…

ASP.NET Web API 中 特性路由(Attribute Routing) 的重名問題

剛才忘了說了&#xff0c;在控制器名重名的情況下&#xff0c;特性路由是不生效的。不然的話就可以利用特性路由解決同名的問題了。 而且這種不生效是真的不生效&#xff0c;不會提示任何錯誤&#xff0c;重名或者什么的&#xff0c;直接會報告404&#xff0c;所以也是個坑。轉…