Linux下time/timestamp相关。

来源:互联网 发布:excel 库存软件 编辑:程序博客网 时间:2024/05/01 16:10

 在Linux下面编程,经常要碰到用到与time/timestamp相关的东西,下面是我以前收集的,放在这里共享。

 

In the file: dbus-sysdeps-unix.c

/**

 * Get current time, as in gettimeofday().

 *

 * @param tv_sec return location for number of seconds

 * @param tv_usec return location for number of microseconds (thousandths)

 */

void

_dbus_get_current_time (long *tv_sec,

                        long *tv_usec)

{

  struct timeval t;

 

  gettimeofday (&t, NULL);

 

  if (tv_sec)

    *tv_sec = t.tv_sec;

  if (tv_usec)

    *tv_usec = t.tv_usec;

}

 

 

How to use it:

 

 

 

/**

 * Get current time, as in gettimeofday().

 *

 * @param tv_sec return location for number of seconds

 * @param tv_usec return location for number of microseconds (thousandths)

 */

void

_dbus_get_current_time (long *tv_sec,

                        long *tv_usec)

{

  struct timeval t;

 

  gettimeofday (&t, NULL);

 

  if (tv_sec)

    *tv_sec = t.tv_sec;

  if (tv_usec)

    *tv_usec = t.tv_usec;

}

 

 

Two time structures:

 

Struct timeval:

  struct   timeval  
  {  
          long   tv_sec;  
          long   tv_usec;  
  }  

 

 

 

 

 

 

 


 

14.11 我知道 localtime() 可以把 time_t 转换结构  struct tm,  ctime() 可以把 time_t 转换可打印的字符串。才能行反向操作,  struct tm 或一字符串转换 time_t

ANSI C 提供了 mktime(),  struct tm 转换 time_t

把一字符串转换 time_t 较难, 是由于可能遇到各的日期和时间格式。某些系提供函 strptime(), 基本上是 strftime()  的反向函。其常用的函 partime() ( RCS 包一起被广泛的 getdate() (有少, 布在 C 的新闻组)见问题  18.18

 

 

C/C++中的日期和时间 time_t(cjp: long)struct tm

2006-07-18 14:07

摘要:

http://wiseman.cnblogs.com
本文础概念入手,探了在C/C++日期和时间操作所用到的结构和函对计时时间取、时间算和示格式等方面行了述。本文大量的例向展示了time.h文件中明的各结构详细使用方法。

关键字:UTC(世界时间),Calendar Time(日历时间),epoch时间点),clock tick时钟计时单元)


1

C/C++中,字符串的操作有很多得注意的问题,同C/C++对时间的操作也有得大家注意的地方。最近,在技群中有很多友也多次C++言中对时间的操作、取和示等等的问题。下面,在篇文章中,主要介C/C++时间和日期的使用方法.

过学习许C/C++可以有很多操作、使用时间的方法。但在之前需要了解一些时间日期念,主要有以下几

Coordinated Universal Time
UTC):协调世界,又世界时间,也就是大家所熟知的格林威治时间Greenwich Mean TimeGMT)。比如,中国内地的时间与UTC+8,也就是UTC+8。美UTC-5

Calendar Time
:日历时间,是用时间点到此时间经过的秒表示的时间这个标时间不同的编译说会有所不同,但编译统来说这个标时间点是不的,该编译中的时间对应的日历时间都通过该标时间衡量,所以可以历时间对时间,但是无论你时区,在同一同一时间,日历时间都是一的。

epoch
时间点。时间点在C/C++中是一用此时间时间点相差的秒(即日历时间表示。

clock tick
时钟计时单元(而不把叫做时钟滴答次),一时钟计时单元的时间长短是由CPU控制的。一clock tick不是CPU的一时钟周期,而是C/C++的一基本计时单位。

可以使用ANSI中的time.h文件。这个头文件中定时间和日期所使用的方法,无是在结构是命名,都具有明C格。下面,我明在C/C++使用日期的时间功能。

2
计时

C/C++
中的计时clock(),而其相型是clock_t。在MSDN中,clock如下:

clock_t clock( void );

这个返回开启这个程序程序中clock()CPU时钟计时单元(clock tick,在MSDN钟时间wall-clock)。其中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)

CJP: #define CLOCKS_PER_SEC 1000000
// 1 million

Cclock(或者C++中的ctime)返回的是clock_t型的CLOCKS_PER_SEC,在time.h文件中定。目前这个值为100使得时间的精度很低,于某些任务来说是不的。CodeWarriorCLOCKS_PER_SEC义为1000000,可以得到毫秒的精度。

 

 


可以看到每千分之一秒(1毫秒),clock()函返回的就加1。下面举个例子,可以使用公式clock()/CLOCKS_PER_SEC算一程自身的时间

void elapsed_time()
{
printf("Elapsed time:%u secs./n",clock()/CLOCKS_PER_SEC);
}

然,也可以用clock数来的机器行一或者理其事件到底花了多少时间

i nclude “stdio.h”
i nclude “stdlib.h”
i nclude “time.h”

int main( void )
{
   long    i = 10000000L;
   clock_t start, finish;
   double  duration;
   /*
量一事件持时间*/
   printf( "Time to do %ld empty loops is ", i );
   start = clock();
   while( i-- )      ;
   finish = clock();
   duration = (double)(finish - start) / CLOCKS_PER_SEC;
   printf( "%f seconds/n", duration );
   system("pause");
}

者的机器上,果如下:

Time to do 10000000 empty loops is 0.03000 seconds

上面我看到时钟计时单元的1毫秒,那么计时的精度也1毫秒,那可不可以通CLOCKS_PER_SEC的定,通的大一些,而使计时精度更高呢?通过尝试你会发现这样是不行的。在C/C++中,最小的计时单位是一毫秒。

3
日期和时间结构

C/C++中,我可通tm结构来获得日期和时间tm结构time.h中的定如下:

#ifndef _TM_DEFINED
struct tm {
        int tm_sec;     /*
值区间为[0,59] */
        int tm_min;     /*
- 值区间为[0,59] */
        int tm_hour;    /*
- 值区间为[0,23] */
        int tm_mday;    /*
月中的日期 - 值区间为[1,31] */
        int tm_mon;     /*
一月始,0代表一月) - 值区间为[0,11] */
        int tm_year;    /*
,其等于实际份减1900 */
        int tm_wday;    /*
星期值区间为[0,6],其中0代表星期天,1代表星期一,以此 */
        int tm_yday;    /*
每年的11始的天值区间为[0,365],其中0代表11日,1代表12日,以此 */
        int tm_isdst;   /*
夏令时标识符,行夏令候,tm_isdst正。不行夏令候,tm_isdst0;不了解情tm_isdst()为负*/
        };
#define _TM_DEFINED
#endif

ANSI C
使用tm结构这种时间表示分解时间(broken-down time)

而日历时间Calendar Time)是通time_t表示的,用time_t表示的时间(日历时间)是时间点(例如:197011000秒)到此的秒。在time.h中,我也可以看到time_t是一整型

#ifndef _TIME_T_DEFINED
typedef long time_t;         /*
时间值 */
#define _TIME_T_DEFINED     /*
避免重 time_t */
#endif

大家可能生疑time_t实际上是整型,到未的某一天,时间点(一般是197011000秒)到那的秒(即日历时间)超出了整形所能表示的的范围怎么办time_t型的值来说所表示的时间不能2038118191407秒。了能表示更久时间,一些编译商引入了64位甚至更的整形数来保存日历时间。比如微Visual C++中采用了__time64_t保存日历时间_time64()数来得日历时间(而不是通使用32位字的time()),这样就可以通过该数型保存300111000秒(不包括该时间点)之前的时间

time.h文件中,我们还可以看到一些函都是以time_t为参数类型或返回值类型的函

double difftime(time_t time1, time_t time0);
time_t mktime(struct tm * timeptr);
time_t time(time_t * timer);
char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);

此外,time.h提供了不同的函数将历时间(一time_t表示的整转换为看到的把年月日分秒分开显示的时间格式tm

struct tm * gmtime(const time_t *timer);                                          
struct tm * localtime(const time_t * timer);

过查阅MSDN,我可以知道Microsoft C/C++ 7.0时间点的time_t象的)是18991231000秒到该时间点所经过的秒,而其版本的Microsoft C/C++和所有不同版本的Visual C++都是算的197011000秒到该时间点所经过的秒

4
日期和时间的函
在本,我向大家展示利用time.h明的函对时间进行操作。些操作包括取时间、算时间间隔、以不同的形式时间容。

4.1
得日历时间

可以通time()数来得日历时间Calendar Time),其原型

time_t time(time_t * timer);

如果经声明了参数timer可以从参数timer返回在的日历时间,同也可以通返回返回在的日历时间,即时间点(例如:197011000秒)到在此的秒。如果参数空(NULL),函数将只通返回返回在的日历时间,比如下面这个例子用前的日历时间

i nclude "time.h"
i nclude "stdio.h"
int main(void)
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
printf("The Calendar Time now is %d/n",lt);
return 0;
}

行的与当时间,我时运行的果是:

The Calendar Time now is 1122707619

其中1122707619就是我行程序的日历时间。即197011000秒到此的秒

4.2
得日期和时间

的日期和时间就是我的年、月、日、、分、秒等信息。2知道些信息都保存在一tm结构体中,那如何历时间保存tm结构象呢?

其中可以使用的函gmtime()localtime()这两个的原型

struct tm * gmtime(const time_t *timer);                                          
struct tm * localtime(const time_t * timer);

其中gmtime()历时间转世界时间(即格林尼治时间),返回一tm结构保存这个时间,而localtime()历时间转本地时间。比如在用gmtime()得的世界时间200573071820秒,那我用localtime()在中得的本地时间会时间标时间晚8,即2005730151820秒。下面是例子:

i nclude "time.h"
i nclude "stdio.h"
int main(void)
{
struct tm *local;
time_t t;
t=time(NULL);
local=localtime(&t);
printf("Local hour is: %d/n",local->tm_hour);
local=gmtime(&t);
printf("UTC hour is: %d/n",local->tm_hour);
return 0;
}

果是:

Local hour is: 15
UTC hour is: 7

4.3
固定的时间格式

可以通asctime()ctime()数将时间以固定的格式示出者的返回都是char*型的字符串。返回的时间格式

星期几 月 日期 ::秒 年/n/0
例如:Wed Jan 02 02:03:55 1980/n/0

其中/n是一行符,/0是一空字符,表示字符串束。下面是两个的原型:

char * asctime(const struct tm * timeptr);
char * ctime(const time_t *timer);

其中asctime()是通tm结构来生成具有固定格式的保存时间信息的字符串,而ctime()是通历时间来生成时间字符串。这样asctime()函只是把tm结构对象中的各时间字符串的相位置就行了,而ctime()函需要先照本地的时间设置,把日历时间转本地时间,然后再生成格式化后的字符串。在下面,如果lt是一非空的time_t量的,那

printf(ctime(<));

等价于:

struct tm *ptr;
ptr=localtime(<);
printf(asctime(ptr));

,下面这个程序的两条printf出的果就是不同的了(除非你将本地时区设为世界时间所在的时区):

i nclude "time.h"
i nclude "stdio.h"
int main(void)
{
struct tm *ptr;
time_t lt;
lt =time(NULL);
ptr=gmtime(<);
printf(asctime(ptr));
printf(ctime(<));
return 0;
}

果:

Sat Jul 30 08:43:03 2005
Sat Jul 30 16:43:03 2005

4.4
自定义时间格式

可以使用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
本地的AMPM的等价
%r 12
时间
%R
示小和分hh:mm
%S
制的秒
%t
水平制表符
%T
分秒:hh:mm:ss
%u
每周的第几天,星期一第一天 (值从06,星期一0
%U
第年的第几周,把星期日做第一天(值从053
%V
每年的第几周,使用基于周的年
%w
制表示的星期几(值从06,星期天0
%W
每年的第几周,把星期一做第一天(值从053
%x
准的日期串
%X
准的时间
%y
的十制年值从099
%Y
部分的十制年
%z
%Z 时区,如果不能得到时区返回空字符。
%%
百分

如果想在是几点了,12示,就象下面段程序:

i nclude “time.h”
i nclude “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

而下面的程序则显前的完整日期:

i nclude
i nclude

void 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);
}

果:

Today is Saturday, day 30 of July in the year 2005.

4.5
算持时间长

候在实际应用中要算一事件持时间长度,比如算打字速度。在第1节计时部分中,我已clock了一例子。Clock()可以精确到毫秒。同,我也可以使用difftime(),但只能精确到秒。的定如下:

double difftime(time_t time1, time_t time0);

返回的以秒算的时间间隔是double型的,但这并该时间具有同double的精确度,是由参数得的(time_t是以秒为单算的)。比如下面一段程序:

i nclude “time.h”
i nclude “stdio.h”
i nclude “stdlib.h”
int main(void)
{
time_t start,end;
start = time(NULL);
system("pause");
end = time(NULL);
printf("The pause used %f seconds./n",difftime(end,start));//<-
system("pause");
return 0;
}


按任意键继续. . .
The pause used 2.000000 seconds.
按任意键继续. . .

可以想像,停的时间不那巧是整整2。其你将上面程序的“//<-”的一行用下面的一行代

printf("The pause used %f seconds./n",end-start);

果是一的。

4.6
分解时间转历时间

的分解时间就是以年、月、日、、分、秒等分量保存的时间结构,在C/C++中是tm结构。我可以使用mktime()函数将tm结构表示的时间转历时间。其函原型如下:

time_t mktime(struct tm * timeptr);

其返回就是化后的日历时间这样就可以先制定一分解时间,然后对这个时间进行操作了,下面的例子可以算出199771日是星期几:

i nclude "time.h"
i nclude "stdio.h"
i nclude "stdlib.h"
int main(void)
{
struct tm t;
time_t t_of_day;
t.tm_year=1997-1900;
t.tm_mon=6;
t.tm_mday=1;
t.tm_hour=0;
t.tm_min=0;
t.tm_sec=1;
t.tm_isdst=0;
t_of_day=mktime(&t);
printf(ctime(&t_of_day));
return 0;
}

果:

Tue Jul 01 00:00:01 1997

在注意了,有了mktime(),是不是我可以操作在之前的任何时间呢?可以通过这种办法算出1945815是星期几?答案是否定的。因为这个时间197011日之前,所以在大多编译器中,这样的程序然可以编译,但时会异止。

5
总结

本文介C/C++中的有日期和时间念,种实述了些函结构的使用方法。认为,和时间的一些念是相重要的,理解念是理解各种时间格式的转换的基,更是些函结构的基

 

 

GDate vs struct tm

起初留心他调试时了半天才陆续发现问题。忽略程,只记结
GDate.year == tm.tm_year + 1900
GDate.month == tm.tm_mon + 1
GDate.day == tm.tm_day

year别没念,有特点的是month,居然也可以不同。

 

 

Linux 中的计时

 

选项

 

为电

示需要 JavaScript 的文选项

 

 

拓展 Tomcat

 

IBM J2EE 用服 WAS CE 新版本 V1.1

级别:

(grandiose11@msn.com)中科院件所

2003 10 01

本文描述了Linux中一些计时问题和解方法。因究的程中我们经常需要统计程序或程序段的耗的性能好坏。因而问题对于我们来说遇到。掌握多种计时方法开发或科工作者都是必掌握的一技能。本文解了在Linux计时当遇到的一些技术问题,相信他人的工作有所助。

实际上,可能还会有其一些方法可以完成本文讨论的任。我仅讨论了我所使用的方法,这并不意味着除此之外的其方法就很差,只不过对说这些方法相对简单有效而已。

Linux中的时间

Linux中,时间扮演着一非常重要的角色,几乎无不在。示如下的信息:

Last login: Tue Sep 23 22:12:50 from 192.168.6.100

 

,我可以使用shutdown命令指定何或多长时间后机器将会时关闭。我有可能还会设置一台Linux时间联网上的一或二级时间器同步,之,在Linux中,我要了解时间

实际上,linux有着自己的计时时钟。可以实验一下,分别执date/sbin/clock(或sbin/hwclock)命令,得到的时间是不同的。

[grandiose@Bygone grandiose]$ date
Sun Sep 28 21:11:02 EDT 2003
[grandiose@Bygone grandiose]$ /sbin/clock
Sun 28 Sep 2003 09:07:07 PM EDT  -0.466994 seconds

 

当你 root 了系统时间之后,请记住以 clock -w 来将统时间写 CMOS 中。

 


 

使用C计时

在用中可以使用C言函gettimeofday 得到时间用格式是:

#include <sys/time.h> 
int gettimeofday(struct timeval *tv, struct timezone *tz); 
int settimeofday(const struct timeval *tv , const struct timezone *tz);
        结构timeval的定义为
strut timeval {
long tv_sec; /*  */
long tv_usec; /* 微秒 */
};

 

可以看出,使用这种方式计时,精度可微秒,也就是10-6秒。计时候,我需要前后gettimeofday,然后算中的差

 
gettimeofday( &start, NULL );
foo(); 
gettimeofday( &end, NULL );
timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec; 
timeuse /= 1000000;

 


 

Shell计时

LinuxShell下,我们经常也使用Shell置的time命令和GNU版的time命令测试程序行的时间

置的time提供的参数选项少,而GNUtime提供了丰富的参数选项,包括指定出文件等功能。

[grandiose@Bygone grandiose]$ /usr/bin/time --output=foo.txt foo

 

上句只有时间信息出到了foo.txt文件中,如果想要包括foo行的果,就需要按下句这样使用:

 
[grandiose@Bygone grandiose]$ /usr/bin/time --output=foo.txt --append foo >foo.txt

 

如果想要控制时间的格式,可以使用-f开关进行格式化:

[grandiose@Bygone grandiose]$ /usr/bin/time --output=foo.txt -f "//t%E real,//t%U user,//t%S sys" foo

 

如果仍需要使用Shell置的time命令,可以用下面一句出至文件:

[grandiose@Bygone grandiose]$ (time foo) 2>foo.txt

 

这样写是因为内置命令time出是到错误的,文件描述符2表示错误stderr。如果想要包括foo行的果,就要这样

[grandiose@Bygone grandiose]$ (time foo) >foo.txt 2>&1

 

其中2>&1的含21 相同,一起送入foo.txt中。

nohup命令可以保证进程在退出系之后仍能行,的常用法。我也可以这样使用nohup

[grandiose@Bygone grandiose]$ nohup time foo

 

果全部出至nohup.out,也包括程序行的时间信息。可以使用下面的时间信息出至文件foo.txt中。

 
[grandiose@Bygone grandiose]$ tail -2 nohup.out > foo.txt

 

了保POSIX一致,出的时间格式nohup.out中的容除外):

real    0m0.007s
user    0m0.002s
sys     0m0.004s

 

可以使用linux下面一些过滤命令如awksedgreptr过滤出我想要得到的容,例如想要得到real对应时间

[grandiose@Bygone grandiose]$ grep real foo.txt | cut -f2,或者
[grandiose@Bygone grandiose]$ sed -n '2p' foo.txt | cut -f2

 

Shell下,出的时间精度毫秒,如果需要微秒计时,那就应该在程序中理。

 


 

核空中的计时

如果要定制自己的设备驱动程序,可能就用到核里的计时功能。Linux核空中的计时与计时不太相同。在核空里,有一全局Jiffies维护前的时间统时钟用有(新的定):

#include <asm/param.h> 
#include <linux/timer.h> 
void add_timer(struct timer_list * timer); 
int del_timer(struct timer_list * timer); 
inline void init_timer(struct timer_list * timer); 

 

结构struct timer_list的定义为

struct timer_list { 
        struct timer_list *next; 
        struct timer_list *prev; 
        unsigned long expires; 
        unsigned long data; 
        void (*function)(unsigned long d); 
}; 

 

其中时间expires是要function时间。一般在add_timerjiffies = jiffies + num,表示在num最小时间间隔后function。系最小时间间所用的硬件平台有 在核心里定了常HZ表示一秒最小时间间隔的目,num*HZ表示num 秒。系统计时时间function把此子程序时队列里除, 因此如果想要每隔一定时间间行一次的,就必function里再一次add_timerfunction参数dtimer里面的data

Jiffies计时精度是百分之一秒,如果在核中需要更精确的计时,就需要用到time_calls.h中的函可用于高精度的时间计算。

 


 

有的候,我需要较为精确地得出被时间这时一般需要多次行取均以消除差。

gettimeofday( &start, NULL );
for ( int i = 0; i< 10; i++ ) foo(); 
gettimeofday( &end, NULL );
timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec; 
timeuse /= 10000000;

 

上面的统计实际也引入了新的差,指令的时间与foo()相比可忽略的这种计时才是可以接受的;否就要除去循指令的时间,才得到正确的统计计时

Linux Shell下,如果统计少,可以:

for i in 1 2 3 4 5 6 7 8 9 10
do
        (time foo) 2>foo.tmp
        grep real foo.tmp | cut -f2 >> foo.txt
done

 

如果计时多,需要:

i=1
while [ $i -le 100 ]
do
        (time foo) 2>foo.tmp
        grep real foo.tmp | cut -f2 >> foo.txt
        i=`expr $i + 1`
done

 

foo.txt容如果手动来计算平均较费时,我可以一段Shell脚本或用C取文件,算其均

/*中分部*/
cut -d'm' -f1 foo.txt > foo.tmp
sum=0
while read line
do
        sum=$(echo "$sum+$line" | bc -l)
done < foo.tmp
echo $sum
/*中秒部*/
cut -d'm' -f2 foo.txt | tr -d 's'> foo.tmp
sum=0
while read line
do
        sum=$(echo "$sum+$line" | bc -l)
done < foo.tmp
echo $sum

 

算出分部秒部和之后,然后再手动计算平均这样要容易得多。注意,上面有使用expr算的原因,是因expr只能支持整型。在Linux shell下,如果要算浮点,就需要使用bc或者是gexpr

 


 

实际上,我们还可以使用PerlPython等多种语言在Linux计时选择工具或计时这与程序或程序段的型以及编写语言相合考精度、时间行次等要求,才能合理可靠地得出程序的时间

 

 

c/c++程中的计时功能

作者 wildpuma 23:06 | | 评论 (25) | 引用 (0) | c/c++

linux下的c/c++程中,计时有三精度,秒(s)、毫秒(ms)、微秒(us)方式的实现互不相同。主要是用clock(),times(),gettimeofday()数来实现。三种数结构好像是clock_t,stuct timeval等。