C語言再學習 -- 時間函式
gmtime函式:可以把time函式得到的結果按照格林尼治時間轉換成一個結構體
localtime函式:可以把time函式得到的結果按照當前時區轉換成一個結構體
asctime函式:可以把一個記錄時間的結構體轉換成字串,一般與上兩個函式合用的
格林時間,與北京時間換算,
/* 時間函式演示 */ #include <stdio.h> #include <time.h> int main() { time_t tm = 0;//long int別名 //time(0)是一個long int空地址 time (&tm); printf ("%s\n", ctime (&tm)); struct tm *p_tm = gmtime (&tm); printf ("%s\n", asctime (p_tm)); struct tm *p_tm1 = localtime (&tm); //宣告語句 printf ("%s\n", asctime (p_tm1)); return 0; } 輸出結果: Sat Jan 14 14:48:10 2017 Sat Jan 14 06:48:10 2017 Sat Jan 14 14:48:10 2017
二、Linux獲取時間戳
第一種方法:微秒級時間戳
檢視:man gettimeofday
功能:獲取/設定時間
NAME gettimeofday, settimeofday - get / set time SYNOPSIS #include <sys/time.h> int gettimeofday(struct timeval *tv, struct timezone *tz); int settimeofday(const struct timeval *tv, const struct timezone *tz); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): settimeofday(): _BSD_SOURCE DESCRIPTION The functions gettimeofday() and settimeofday() can get and set the time as well as a timezone. The tv argument is a struct timeval (as specified in <sys/time.h>): struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }; and gives the number of seconds and microseconds since the Epoch (see time(2)). The tz argument is a struct timezone: struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of DST correction */ }; If either tv or tz is NULL, the corresponding structure is not set or returned.
下面是個簡單的例子,用來統計程式的執行時間:
第二種方法:毫秒級時間戳,微秒級精度不夠檢視:man ftime功能:返回的日期和時間#include <stdio.h> #include <sys/time.h> int main(void) { struct timeval start,end; gettimeofday( &start, NULL ); /*測試起始時間*/ usleep (10000); //使用 usleep gettimeofday( &end, NULL ); /*測試終止時間*/ int timeuse = (end.tv_usec - start.tv_usec); printf("執行時間為:%d us\n",timeuse); return 0; } 輸出結果: 10193 us
NAME
ftime - return date and time
SYNOPSIS
#include <sys/timeb.h>
int ftime(struct timeb *tp);
DESCRIPTION
This function returns the current time as seconds and milliseconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). The time is
returned in tp, which is declared as follows:
struct timeb {
time_t time;
unsigned short millitm;
short timezone;
short dstflag;
};
Here time is the number of seconds since the Epoch, and millitm is the number of milliseconds since time seconds since the Epoch.
The timezone field is the local timezone measured in minutes of time west of Greenwich (with a negative value indicating minutes
east of Greenwich). The dstflag field is a flag that, if nonzero, indicates that Daylight Saving time applies locally during the
appropriate part of the year.
POSIX.1-2001 says that the contents of the timezone and dstflag fields are unspecified; avoid relying on them.
RETURN VALUE
This function always returns 0. (POSIX.1-2001 specifies, and some systems document, a -1 error return.)
tp結構定義:struct timeb{
time_t time; /* 為1970-01-01至今的秒數*/
unsigned short millitm; /* 千分之一秒即毫秒 */
short timezonel; /* 為目前時區和Greenwich相差的時間,單位為分鐘 */
short dstflag; /* 為日光節約時間的修正狀態,如果為非0代表啟用日光節約時間修正 */
};下面是個簡單的例子:
#include <stdio.h>
#include <sys/timeb.h>
long long getSystemTime() {
struct timeb t;
ftime(&t);
return (1000 * t.time + t.millitm) * 1000;
}
int main() {
long long start = getSystemTime();
usleep(3000);
long long end = getSystemTime();
printf("time: %lld us\n", end-start);
return 0;
}
輸出結果:
3000 us
第三種方法:秒級時間戳檢視:man difftime 功能:返回兩個time_t型變數之間的時間間隔,即 計算兩個時刻之間的時間差。NAME
difftime - calculate time difference
SYNOPSIS
#include <time.h>
double difftime(time_t time1, time_t time0);
DESCRIPTION
The difftime() function returns the number of seconds elapsed between time time1 and time time0, represented as a double. Each of
the times is specified in calendar time, which means its value is a measurement (in seconds) relative to the Epoch, 1970-01-01
00:00:00 +0000 (UTC).
下面是個簡單的例子:#include <stdio.h>
#include <time.h>
int main(){
time_t t_start, t_end;
t_start = time(NULL) ;
sleep(3);
t_end = time(NULL) ;
printf("time: %.0f s\n", difftime(t_end,t_start)) ;
return 0;
}
輸出結果:
time: 3 s
第四種方法:C/C++中的計時函式clock()在MSDN中,查得對clock函式定義如下:clock_t clock(void) ;
簡單而言,就是該程式從啟動到函式呼叫佔用CPU的時間。這個函式返回從“開啟這個程式程序”到“程式中呼叫clock()函式”時之間的CPU時鐘計時單元(clock tick)數,在MSDN中稱之為掛鐘時間(wal-clock);若掛鐘時間不可取,則返回-1。其中clock_t是用來儲存時間的資料型別。
在time.h檔案中,我們可以找到對它的定義:
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif
很明顯,clock_t是一個長整形數。在time.h檔案中,還定義了一個常量CLOCKS_PER_SEC,它用來表示一秒鐘會有多少個時鐘計時單元,其定義如下:
#define CLOCKS_PER_SEC ((clock_t)1000)
在linux系統下,CLOCKS_PER_SEC的值可能有所不同,目前使用的linux打印出來的值是1000000,表示的是微秒。這一點需要注意。
可以看到每過千分之一秒(1毫秒),呼叫clock()函式返回的值就加1。下面舉個例子,你可以使用公式clock()/CLOCKS_PER_SEC來計算一個程序自身的執行時間:
void elapsed_time()
{
printf("Elapsed time:%u secs.\n",clock()/CLOCKS_PER_SEC);
}
當然,你也可以用clock函式來計算你的機器執行一個迴圈或者處理其它事件到底花了多少時間:#include"time.h"
#include"stdlib.h"
#include"stdio.h"
void sleep (clock_t wait);
int main (void)
{
long i = 600000000L;
clock_t start, finish;
double duration;
printf( "延時3秒\n" );
sleep( (clock_t)3 * CLOCKS_PER_SEC );
printf( "Done!\n" );
start = clock();
printf("程式啟動,start = %ld\n", start);
while( i-- )
;
finish = clock();
printf("迴圈結束,finish = %ld\n", finish);
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "CPU 佔用的總時間: %2.1f seconds\n", duration );
printf("程式退出...\n");
return 0;
}
void sleep( clock_t wait )
{
clock_t goal;
goal = wait + clock();
while( goal > clock() )
;
}
輸出結果:
延時3秒
Done!
程式啟動,start = 3000000
迴圈結束,finish = 4810000
CPU 佔用的總時間: 1.8 seconds
程式退出...
它的另一個功能:利用clock()函式和for迴圈完成程式定時暫停
#include <stdio.h>
#include<time.h>
int main(void)
{
int b = 0, i = 0;
b=clock()/CLOCKS_PER_SEC;
for(i=0;i<10;)//完成100秒定時
{
i = i-b;
i = clock()/CLOCKS_PER_SEC;
}
printf ("finish\n");
return 0;
}
輸出結果:
time ./a.out
finish
real 0m10.171s
user 0m2.180s
sys 0m7.820s
第五種方法:使用time 命令最簡單的方法了,上面的例子其實已經用到。在執行可執行檔案的時候,使用如下命令,便可以統計該程式的執行時間。time ./a.out
real 0m10.171s
user 0m2.180s
sys 0m7.820s
time命令,統計的結果包涵程式載入和退出的時間,統計的結果比較粗糙。若想得出函式執行時間較為準確的結果,建議使用上面的幾種方法。三、定時器:
檢視:man getitimer
NAME
getitimer, setitimer - get or set value of an interval timer
SYNOPSIS
#include <sys/time.h>
int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
DESCRIPTION
The system provides each process with three interval timers, each decrementing in a distinct time domain. When any timer expires, a
signal is sent to the process, and the timer (potentially) restarts.
ITIMER_REAL decrements in real time, and delivers SIGALRM upon expiration.
ITIMER_VIRTUAL decrements only when the process is executing, and delivers SIGVTALRM upon expiration.
ITIMER_PROF decrements both when the process executes and when the system is executing on behalf of the process. Coupled with
ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application in user and kernel space.
SIGPROF is delivered upon expiration.
Timer values are defined by the following structures:
struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
The function getitimer() fills the structure pointed to by curr_value with the current setting for the timer specified by which (one
of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF). The element it_value is set to the amount of time remaining on the timer, or zero
if the timer is disabled. Similarly, it_interval is set to the reset value.
The function setitimer() sets the specified timer to the value in new_value. If old_value is non-NULL, the old value of the timer
is stored there.
Timers decrement from it_value to zero, generate a signal, and reset to it_interval. A timer which is set to zero (it_value is zero
or the timer expires and it_interval is zero) stops.
Both tv_sec and tv_usec are significant in determining the duration of a timer.
Timers will never expire before the requested time, but may expire some (short) time afterward, which depends on the system timer
resolution and on the system load; see time(7). (But see BUGS below.) Upon expiration, a signal will be generated and the timer
reset. If the timer expires while the process is active (always true for ITIMER_VIRTUAL) the signal will be delivered immediately
when generated. Otherwise the delivery will be offset by a small time dependent on the system loading.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
第一個引數:計時器的型別
ITIMER_REAL--真實計時器,主要描述程序執行的真實時間,通過產生SIGALRM訊號工作(掌握)
ITIMER_VIRTUAL 虛擬計時器,主要描述程序在使用者空間消耗的時間,通過產生SIGVTALRM訊號工作(瞭解)
ITIMER_PROF--實用計時器,主要描述程序在使用者空間和核心空間共同消耗的時間,通過產生SIGPROF訊號工作(瞭解)
第二個引數:計時器的新值
struct itimerval
{
struct timeval it_interval; /* next value */ //間隔時間
struct timeval it_value; /* current value */ //啟動時間
};
struct timeval
{
long tv_sec; /* seconds */ //秒數
long tv_usec; /* microseconds */ //微秒
};
第三個引數:用於獲取計時器的舊值,不想帶直接給NULL
函式功能:主要用於使用者獲取/設定計時器的數值
下面是個簡單的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/time.h>
void fa(int signo)
{
printf("貪吃蛇移動了一步\n");
}
int main()
{
struct itimerval t_start, t_end;
getitimer (ITIMER_REAL, &t_start);
printf("Start time: %ld us\n", t_start.it_value.tv_usec);
//設定SIGALRM進行自定義處理
signal(SIGALRM,fa);
struct itimerval timer;
//設定啟動時間
timer.it_value.tv_sec=0;//秒數
timer.it_value.tv_usec=30000;//微秒
//設定間隔時間
timer.it_interval.tv_sec=1;
timer.it_interval.tv_usec=0;
//設定真實計時器開始工作
int res=setitimer(ITIMER_REAL,&timer,NULL);
if(-1==res)
{
perror("settimer"),exit(-1);
}
getitimer (ITIMER_REAL, &t_end);
printf("End time: %ld us\n", t_end.it_value.tv_usec);
long cost_time = t_end.it_value.tv_usec - t_start.it_value.tv_usec;
printf("Cost time: %ld us\n", cost_time);
while (1);
return 0;
}
輸出結果:
Start time: 0 us
End time: 29997 us
Cost time: 29997 us
貪吃蛇移動了一步
貪吃蛇移動了一步
貪吃蛇移動了一步
貪吃蛇移動了一步
貪吃蛇移動了一步
^C
擴充套件:
1、預定義巨集裡有 __TIME__
__TIME__原始檔編譯時間,格式為“hh: mm: ss”
#include <stdio.h>
int main (void)
{
printf ("The time is %s\n", __TIME__);
return 0;
}
輸出結果:
The time is 18:24:24
2、標頭檔案 time.h
日期和時間函式: 本類別給出時間和日期處理函式
----------------------------------------
下面的函式感興趣的可以自行百度
時間操作函式得到處理器時間 clock
得到時間差difftime
設定時間mktime
得到時間time
時間轉換函式 得到以ASCII碼錶示的時間asctime
得到字串表示的時間ctime
得到指定格式的時間strftime
__BEGIN_NAMESPACE_STD
/* Time used by the program so far (user time + system time).
The result / CLOCKS_PER_SECOND is program time in seconds. */
extern clock_t clock (void) __THROW;
/* Return the current time and put it in *TIMER if TIMER is not NULL. */
extern time_t time (time_t *__timer) __THROW;
/* Return the difference between TIME1 and TIME0. */
extern double difftime (time_t __time1, time_t __time0)
__THROW __attribute__ ((__const__));
/* Return the `time_t' representation of TP and normalize TP. */
extern time_t mktime (struct tm *__tp) __THROW;
/* Format TP into S according to FORMAT.
Write no more than MAXSIZE characters and return the number
of characters written, or 0 if it would exceed MAXSIZE. */
extern size_t strftime (char *__restrict __s, size_t __maxsize,
__const char *__restrict __format,
__const struct tm *__restrict __tp) __THROW;
__END_NAMESPACE_STD
3、根據檔案時間戳的相關屬性來查詢檔案我們可以使用 stat 命令來檢視一個檔案的時間資訊,如下:
[email protected]:/mnt/test# stat ./
檔案:"./"
大小:4096 塊:8 IO 塊:4096 目錄
裝置:801h/2049d Inode:291601 硬連結:2
許可權:(0755/drwxr-xr-x) Uid:( 1000/ zslf) Gid:( 1000/ zslf)
最近訪問:2016-11-25 09:45:24.699140785 +0800
最近更改:2016-11-25 09:45:22.255140690 +0800
最近改動:2016-11-25 09:45:22.255140690 +0800
建立時間:-
-atime、-mtime、-ctime、-amin、-mmin、-cmin這裡的 -atime、-mtime、-ctime 分別對應的是 “最近一次訪問時間”,“最近一次內容修改時間”,“最近一次屬性修改時間”,這裡的atime的單位指的是“天”,amin 的單位是分鐘。
檔案的 Access time,atime:是在讀取檔案或者執行檔案時更改的。
檔案的 Modified time,mtime: 是在寫入檔案時隨檔案內容的更改而更改的。
檔案的 Create time,ctime :是在寫入檔案、更改所有者、許可權或連結設定時隨 Inode 的內容更改而更改的。
檔案各種事件標記的顯示方法
ls -lc filename 列出檔案的 ctime
ls -lu filename 列出檔案的 atime
ls -l filename 列出檔案的 mtime
檢視:man ls
-c with -lt: sort by, and show, ctime (time of last modification of file status information) with -l: show ctime and sort by
name otherwise: sort by ctime, newest first
-u with -lt: sort by, and show, access time with -l: show access time and sort by name otherwise: sort by access time
-l use a long listing format
查詢在五天內沒有訪問過的檔案
[email protected]:/mnt/test# find ./ -atime +5
查詢在五天內訪問過的檔案
[email protected]:/mnt/test# find ./ -atime -5
./
./f.sh
./g.sh
./a.sh
./c.sh
./b.sh
4、UNIX時間戳