嵌入式 Linux时间函数

2019-07-12 14:17发布

Linux的时间函数

 一、时间相关说明 格林威治时间表示0时区的标准时间。其他时区的时间和此标准时间均有时间差。UTC(Universal TimeCoordinated)是世界协调时间,是格林威治时间在互联网中的表示方法 二、标准C语言时间函数 1、time(取得本地目前的时间秒数) #include time_t time(time_t *t); 函数说明 此函数会返回从公元1970年1月1日的UTC时间从0时0分0秒(Epoch,linux纪元)算起到现在所经过的秒数。如果t并非空指针的话,此函数也会将返回值存到t指针所指的内存。 返回值 成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno中。 time_t 定义为long int 范例  #include mian() { long int seconds=time((time_t*)NULL); printf(“%d ”,seconds); } 执行  9.73E+08 2、gmtime(根据本地时间取得目前的UTC时间) #include struct tm*gmtime(consttime_t*timep); 函数说明  gmtime()将参数timep所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。 结构tm的定义为 struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; }; int tm_sec 代表目前秒数,正常范围为0-59,但允许至61秒 int tm_min 代表目前分数,范围0-59 int tm_hour 从午夜算起的时数,范围为0-23 int tm_mday 目前月份的日数,范围01-31 int tm_mon 代表目前月份,从一月算起,范围从0-11 int tm_year 从1900 年算起至今的年数 int tm_wday 一星期的日数,从星期一算起,范围为0-6 int tm_yday 从今年1月1日算起至今的天数,范围为0-365 int tm_isdst 日光节约时间的旗标 此函数返回的时间日期未经时区转换,而是UTC时间。 返回值  返回结构tm代表目前UTC时间 范例  #include 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 ”,wday[p->tm_wday], p->tm_hour, p->tm_min,p->tm_sec); } 执行  2000/10/28 Sat8:15:38 3、localtime(取得当地目前UTC时间和日期)  #include struct tm *localtime(const time_t *timep); 函数说明 localtime()将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm返回。结构tm的定义请参考gmtime()。此函数返回的时间日期已经转换成当地时区。 返回值 返回结构tm代表目前的当地时间。 范例  #include 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),( l+p->tm_mon), p->tm_mday); printf(“%s%d:%d:%d ”,wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec); } 执行  2000/10/28 Sat11:12:22 4、ctime(将时间和日期以字符串格式表示)  #include char *ctime(const time_t *timep); 函数说明 ctime()将参数timep所指的time_t结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为“Wed Jun 30 21 :49 :081993 ”。若再调用相关的时间日期函数,此字符串可能会被破坏。 返回值 返回一字符串表示目前当地的时间日期。 范例#include main() { time_t timep; time (&timep); printf(“%s”,ctime(&timep)); } 执行  Sat Oct 28 10 : 12: 05 2000 5、asctime(将时间和日期以字符串格式表示)  #include char * asctime(const struct tm *timeptr); 函数说明 asctime()将参数timeptr所指的tm结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为:“WedJun 30 21:49:08 1993 ” 返回值 若再调用相关的时间日期函数,此字符串可能会被破坏。此函数与ctime不同处在于传入的参数是不同的结构。 附加说明 返回一字符串表示目前当地的时间日期。 范例#include main() { time_t timep; time (&timep); printf(“%s”,asctime(gmtime(&timep))); } 执行  Sat Oct 2802:10:06 2000 6、mktime(将时间结构数据转换成经过的秒数)  #include time_t mktime(strcut tm * timeptr); 函数说明 mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0秒算起至今的UTC时间所经过的秒数。 返回值  返回经过的秒数。 范例  #include main() { time_t timep; strcut tm *p; time(&timep); printf(“time() : %d ”,timep); p=localtime(&timep); timep = mktime(p); printf(“time()->localtime()->mktime():%d ”,timep); } 执行 time():974943297 time()->localtime()->mktime():974943297 设置系统时间 标准C库中只有获取系统时间的API,好像还没有设置系统时间的API,本文将谈谈如何在linuxwindows平台设置系统时间,最后给出一个与平台无关的设置系统时间的封闭函数。 Linux下设置系统时间: 1Linux下设置系统时间的函数有好几个,先来看看最常用的stime()函数,这个函数只能精确到秒。 #define _SVID_SOURCE #include int stime(time_t *t); 参数说明: t是以秒为单位的时间值,从GMT197011000秒开始计算。 返回值: 成功返回0,错误返回-1errno错误码,EFAULT表示传递的参数错误,如时间值是无效的值,EPERM表示权限不够,注意只有root用户才有修改系统时间的权限。如果要让普通程序修改系统时间,可以先切换到root用户操作,修改完成后,再切换到普通用户,或者用命令chmod+s给执行文件加上root用户的权限。 2linux是如何管理时间的? 在系统启动时,Linux操作系统将时间从CMOS中读到系统时间变量中,以后修改时间通过修改系统时间实现。为了保持系统时间与CMOS时间的一致性,Linux每隔11分钟会将系统时间写入CMOS,同步时间。从这可以看出,获取系统时间有两个途径,一种是从CMOS中读,一种是从系统中读,但修改时间却只有一种,即修改linux系统中的时间,而修改CMOS中的时间是无效的,因为CMOS中的时间会被定时重写掉。另外还有一点要注意,修改了系统时间并不是马上生效的,假如你修改了系统时间并马上关机,再开机的时候,时间还是原来的,因为修改的时间还没有来得及写入CMOS中。 3.通过settimeofday()函数来设置系统时间,这个函数设置的精度可以精确到微秒。 #include int settimeofday(const struct timeval *tv , const structtimezone *tz); struct timeval {    time_t     tv_sec;        suseconds_ttv_usec;    }; struct timezone {    inttz_minuteswest;        inttz_dsttime;         }; tz参数为时区,时区结构中tz_dsttimelinux中不支持,应该置为0,通常将参数tz设置为NULL,表示使用当前系统的时区。该函数是glib中的,但在mingw中没有实现。 该函数返回值与stime()一样,同样也需要root权限。 4.设置CMOS时间,其实它是通过RTCReal-time clock)设备驱动来完成的,你可以用ioctl()函数来设置时间,当然也可以通过操作/dev/rtc设备文件,在此就不详细说明了。 二、windows下设置系统时间 1.设置当前时区的时间 #include BOOL SetLocalTime(const SYSTEMTIME*lpSystemTime); typedef struct _SYSTEMTIME { // st     WORD wYear;    WORD wMonth; //月份从1开始    WORD wDayOfWeek; //SetLocalTime()不使用这个参数    WORD wDay;    WORD wHour;    WORD wMinute;    WORD wSecond;    WORD wMilliseconds; }SYSTEMTIME; 函数成功返回非零,失败返回零。注意要求调用进程必需有SE_SYSTEMTIME_NAME权限。 2.另外还有一个函数SetSystemTime(),它的参数与SetLocalTime一样,只不过以UTC时区为基准的。 BOOL SetSystemTime(const SYSTEMTIME*lpSystemTime); 二、一个封装的设置系统时间的函数 //设置成功返回true,否则返回false       bool set_local_time(struct tm& t) { #ifdef _WIN32       SYSTEMTIME st;       memset(&st, 0, sizeof(SYSTEMTIME));       st.wYear = t.tm_year + 1970; //注意structtm结构中的年是从1970年开始的计数       st.wMonth = t.tm_mon + 1; //注意structtm结构中的月份是从0开始的       st.wDay = t.tm_mday;       st.wHour = t.tm_hour;       st.wMinute = t.tm_min;       st.wSecond = t.tm_sec;       if(!SetLocalTime(&st))              return true;              else                     return false;       #else              //struct tm结构时间转换成GMT时间time_t              struct time_t st;              st = mktime(&t);              if(st==-1)                     return false;              if(!stime(st))                     return true;              else                     return false; #endif }   三、linux系统时间函数 1、gettimeofday(取得目前的时间)        #include #include
int gettimeofday ( struct timeval * tv, struct timezone * tz ) 函数说明 gettimeofday()会把目前的时间有tv所指的结构返回,当地时区的信息则放到tz所指的结构中。 timeval结构定义为: struct timeval{ long tv_sec;   long tv_usec; }; timezone 结构定义为: struct timezone{ int tz_minuteswest; int tz_dsttime; }; 上述两个结构都定义在/usr/include/sys/time.h。tz_dsttime 所代表的状态如下 DST_NONE DST_USA DST_AUST DST_WET DST_MET DST_EET DST_CAN DST_GB DST_RUM DST_TUR DST_AUSTALT 返回值 成功则返回0,失败返回-1,错误代码存于errno。附加说明EFAULT指针tv和tz所指的内存空间超出存取权限。       #include #include main(){ struct timeval tv; struct timezone tz; gettimeofday (&tv , &tz); printf(“tv_sec; %d ”, tv,.tv_sec); printf(“tv_usec; %d ”,tv.tv_usec); printf(“tz_minuteswest; %d ”,tz.tz_minuteswest); printf(“tz_dsttime,%d ”,tz.tz_dsttime); } 执行  tv_sec:974857339 tv_usec:136996 tz_minuteswest:-540 tz_dsttime:0   2、settimeofday(设置目前时间)       #include #include int settimeofday ( const struct timeval*tv,const struct timezone *tz);   函数说明 settimeofday()会把目前时间设成由tv所指的结构信息,当地时区信息则设成tz所指的结构。详细的说明请参考gettimeofday()。注意,只有root权限才能使用此函数修改时间。   返回值 成功则返回0,失败返回-1,错误代码存于errno。 错误代码  EPERM并非由root权限调用settimeofday(),权限不够。 EINVAL 时区或某个数据是不正确的,无法正确设置时间。 3、clock_gettime(获取指定时钟的时间值)       #include #include int clock_gettime( clockid_tclock_id,struct timespec * tp ); 说明:clock_id指定要获取时间的时钟,根据Posix的指定可以是以下值: CLOCK_REALTIME Systemwide realtime clock.   CLOCK_MONOTONIC Represents monotonic time. Cannot beset.   CLOCK_PROCESS_CPUTIME_ID High resolution per-process timer.   CLOCK_THREAD_CPUTIME_ID Thread-specific timer.   CLOCK_REALTIME_HR High resolution version ofCLOCK_REALTIME.   CLOCK_MONOTONIC_HR High resolution version ofCLOCK_MONOTONIC.   struct timespec { time_ttv_sec;        long tv_nsec;       };   4、adjtimex(tune kernel clock)       #include #include int adjtimex(struct timex *buf); 说明: Linux uses  David L. Mills' clock adjustment algorithm(see RFC 1305).The system call adjtimex() reads and optionally setsadjustment parame-ters  for this algorithm.   It takes a pointer to a timex structure,updates kernel parametersfrom  field values,  and returns  the  samestructure  with current  kernelvalues.  This structure is declared asfollows: struct timex { intmodes;           longoffset;         longfreq;           longmaxerror;       longesterror;       intstatus;          longconstant;       longprecision;      longtolerance;      struct timeval time; longtick;           }; The modes field determines whichparameters, if any, to set.   It  maycontain a bitwise-or combination of zero or more of the followingbits:   #defineADJ_OFFSET           0x0001 #defineADJ_FREQUENCY        0x0002 #defineADJ_MAXERROR         0x0004 #defineADJ_ESTERROR         0x0008 #defineADJ_STATUS           0x0010 #defineADJ_TIMECONST        0x0020 #defineADJ_TICK             0x4000 #define ADJ_OFFSET_SINGLESHOT 0x8001  Ordinary users are restricted to a zerovalue for mode.  Only the supe-ruser mayset any parameters.  RETURN VALUE On success, adjtimex() returns theclock state:  #defineTIME_OK   0 #define TIME_INS 1 #define TIME_DEL 2 #define TIME_OOP 3 #define TIME_WAIT 4 #define TIME_BAD  5  On failure, adjtimex() returns -1 andsets errno.  ERRORS EFAULT buf does not point to writablememory.  EINVAL An attempt is made to set buf.offset toa value outside the range -131071 to +131071, or to set buf.statusto a value other than those listed above, or to set buf.tick to avalue outside the range 900000/HZ to 1100000/HZ, where HZ is thesystem  timer interruptfrequency.  EPERM buf.mode is non-zero and the callerdoes not have sufficient privilege.Under Linux the CAP_SYS_TIMEcapability is required. CONFORMING TO adjtimex() is Linux specific and shouldnot be used in programs intended to be portable. See adjtime(3) fora more portable, but less flexible, method of adjusting the systemclock.