嵌入式 Linux时间函数

原创 2013年12月02日 14:52:03

Linux的时间函数

 一、时间相关说明

格林威治时间表示0时区的标准时间。其他时区的时间和此标准时间均有时间差。UTC(Universal TimeCoordinated)是世界协调时间,是格林威治时间在互联网中的表示方法

二、标准C语言时间函数

1、time(取得本地目前的时间秒数)

#include <time.h>

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 <time.h>

mian()

{

long int seconds=time((time_t*)NULL);

printf(“%d\n”,seconds);

}

执行  9.73E+08

2、gmtime(根据本地时间取得目前的UTC时间)

#include <time.h>

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 <time.h>

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

}

执行  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 <time.h>

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\n”,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\n”。若再调用相关的时间日期函数,此字符串可能会被破坏。

返回值 返回一字符串表示目前当地的时间日期。

范例#include <time.h>

main()

{

time_t timep;

time (&timep);

printf(“%s”,ctime(&timep));

}

执行  Sat Oct 28 10 : 12: 05 2000

5、asctime(将时间和日期以字符串格式表示) 

#include <time.h>

char * asctime(const struct tm *timeptr);

函数说明 asctime()将参数timeptr所指的tm结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为:“WedJun 30 21:49:08 1993\n”

返回值 若再调用相关的时间日期函数,此字符串可能会被破坏。此函数与ctime不同处在于传入的参数是不同的结构。

附加说明 返回一字符串表示目前当地的时间日期。

范例#include <time.h>

main()

{

time_t timep;

time (&timep);

printf(“%s”,asctime(gmtime(&timep)));

}

执行  Sat Oct 2802:10:06 2000

6、mktime(将时间结构数据转换成经过的秒数) 

#include <time.h>

time_t mktime(strcut tm * timeptr);

函数说明 mktime()用来将参数timeptr所指的tm结构数据转换成从公元1970年1月1日0时0分0秒算起至今的UTC时间所经过的秒数。

返回值  返回经过的秒数。

范例 

#include <time.h>

main()

{

time_t timep;

strcut tm *p;

time(&timep);

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

p=localtime(&timep);

timep = mktime(p);

printf(“time()->localtime()->mktime():%d\n”,timep);

}

执行 time():974943297

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

设置系统时间

标准C库中只有获取系统时间的API,好像还没有设置系统时间的API,本文将谈谈如何在linuxwindows平台设置系统时间,最后给出一个与平台无关的设置系统时间的封闭函数。

Linux下设置系统时间:

1Linux下设置系统时间的函数有好几个,先来看看最常用的stime()函数,这个函数只能精确到秒。

#define _SVID_SOURCE

#include <time.h>

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 <time.h>

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 <time.h>

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 <time.h>
#include <stdio.h>

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 <time.h>
#include <stdio.h>

main(){

struct timeval tv;

struct timezone tz;

gettimeofday (&tv , &tz);

printf(“tv_sec; %d\n”, tv,.tv_sec);

printf(“tv_usec; %d\n”,tv.tv_usec);

printf(“tz_minuteswest; %d\n”,tz.tz_minuteswest);

printf(“tz_dsttime,%d\n”,tz.tz_dsttime);

}

执行  tv_sec:974857339

tv_usec:136996

tz_minuteswest:-540

tz_dsttime:0

 

2、settimeofday(设置目前时间)

      #include <time.h>
#include <stdio.h>

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 <time.h>
#include <stdio.h>

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 <time.h>
#include <stdio.h>

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 

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.

相关文章推荐

腾讯开源ncnn:示例程序运行

本博记录为卤煮使用时的记录,属于事后回忆记录,如有疏漏,请指正。 卤煮:非文艺小燕儿 本博地址:ncnn:示例程序运行 感谢开源共享的各位大牛们,让我们能够站在巨人的肩膀上前行。 ncnn g...

C语言中常用计时方法总结

C语言中常用计时方法总结 1. time() 头文件:time.h 函数原型:time_t time(time_t * timer) 功能:返回以格林尼治时间(GMT)为标准,从1970年...
  • fz_ywj
  • fz_ywj
  • 2012年10月25日 09:46
  • 30494

嵌入式学习笔记_Linux(二)——Linux时间编程

Linux时间编程 获取日历时间:#include time_t time(time_t *tloc);功能:获取当前系统时间,即从1970年1月1日0点到现在所经历的秒数 时间转换:struct...

嵌入式 linux中probe函数中传递的参数来源(上)

上一篇中,我们追踪了probe函数在何时调用,知道了满足什么条件会调用probe函数,但probe函数中传递的参数我们并不知道在何时定义,到底是谁定义的,反正不是我们在驱动中定义的(当然,驱动中也不会...
  • skdkjxy
  • skdkjxy
  • 2014年09月30日 14:59
  • 706

嵌入式 linux中probe函数传递参数的寻找(下)

通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个连通之日,也是任督二脉打通之时。先从设备定义去查看,在mach...
  • skdkjxy
  • skdkjxy
  • 2014年09月30日 14:58
  • 649

嵌入式 Linux 通过信号机制在进程间传递参数中的几个主要函数解析

1. sigqueue() 用于信号的发送 函数功能: 发送信号给特定的某个进程 使用头文件: #include 函数原型:  int sigqueue(pid_t pid, int...
  • skdkjxy
  • skdkjxy
  • 2014年08月29日 17:19
  • 403

嵌入式 Linux系统编程(二)——文件描述符控制函数fcntl

嵌入式 Linux系统编程(二)——文件描述符控制函数fcntl    由于fcntl函数实在过于灵活和复杂,本文将fcntl函数从文件IO中单独列出来,便于详细解读。函数原型如下:#include ...

嵌入式 mysql长时间没操作会自动关闭连接default是8hours解决方法集合mysql_ping(可能部分重复)

1、 mysql5数据库连接超时问题的解决办法 最近碰到一个mysql5数据库的问题。就是一个标准的servlet/tomcat网络应用,后台使用mysql数据库。问题是待机一晚上后,第二天早上第一次...
  • skdkjxy
  • skdkjxy
  • 2013年12月19日 13:28
  • 1699

嵌入式设备ntp同步时间的一些笔记

本文主要记录平常积累的关于ntp的东东。 为了连接ntp服务器,设备必须连外网,设置方法不尽相同,此处从略。 ntp服务器有很多,但有些是用不了的。测试中用的是202.120.2.101,它是上海交通...
  • subfate
  • subfate
  • 2013年10月20日 11:33
  • 1261

嵌入式OS入门笔记-以RTX为案例:四.简单的时间管理

上一节简单记录了进程task。有了进程以后,我们需要关心怎么样分配CPU资源(或者运行时间)给每个进程。那么就要引入排程(scheduling)的概念。排程一般都是OS里面非常重要的一部分,但是在深入...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:嵌入式 Linux时间函数
举报原因:
原因补充:

(最多只允许输入30个字)