metootxy

导航

 

上次讲了alarm后,大致看了一下内核的时间表示,所以就记录一下。

一、时间的表示方法:

Linux内核中表示时间的结构体和数据类型有5种:struct timeval; struct timespec; struct timezone; struct tm; time_t; struct rtc_time;

具体其声明的头文件在:include/linux/time.h

 12 #ifndef _STRUCT_TIMESPEC
 13 #define _STRUCT_TIMESPEC
 14 struct timespec {
 15         __kernel_time_t tv_sec;                 /* seconds */
 16         long            tv_nsec;                /* nanoseconds */
 17 };
 18 #endif

timespec由秒和纳秒组成;精度要比timeval的要高,使用下列函数获得:

184 extern void getnstimeofday(struct timespec *tv);  

 

 20 struct timeval {
 21         __kernel_time_t         tv_sec;         /* seconds */
 22         __kernel_suseconds_t    tv_usec;        /* microseconds */
 23 };
 24 

timeval由秒和微妙组成;使用下列函数获得

extern void do_gettimeofday(struct timeval *tv);

 

 25 struct timezone {                                                                                                                                                                          
 26         int     tz_minuteswest; /* minutes west of Greenwich */
 27         int     tz_dsttime;     /* type of dst correction */
 28 };
 29 

 

205 struct tm {
206         /*
207          * the number of seconds after the minute, normally in the range
208          * 0 to 59, but can be up to 60 to allow for leap seconds
209          */
210         int tm_sec;
211         /* the number of minutes after the hour, in the range 0 to 59*/
212         int tm_min;
213         /* the number of hours past midnight, in the range 0 to 23 */
214         int tm_hour;
215         /* the day of the month, in the range 1 to 31 */
216         int tm_mday;
217         /* the number of months since January, in the range 0 to 11 */
218         int tm_mon;
219         /* the number of years since 1900 */
220         long tm_year;
221         /* the number of days since Sunday, in the range 0 to 6 */
222         int tm_wday;
223         /* the number of days since January 1, in the range 0 to 365 */
224         int tm_yday;
225 };

tm是很直观的表示时间的方法;

 

8 typedef __kernel_time_t         time_t;

time_t该类型被定义在include/linux/types.h中,它是一个长整型,用来表示1970年以来的秒数。

并且在内核中定义了6中时钟:

311         
312 /*      
313  * The IDs of the various system clocks (for POSIX.1b interval timers):
314  */
315 #define CLOCK_REALTIME                  0//表示系统当前时间,从1970年1.1日算起
316 #define CLOCK_MONOTONIC                 1//系统的启动时间,改时间是不会被改变的;
317 #define CLOCK_PROCESS_CPUTIME_ID        2
318 #define CLOCK_THREAD_CPUTIME_ID         3
319 #define CLOCK_MONOTONIC_RAW             4
320 #define CLOCK_REALTIME_COARSE           5
321 #define CLOCK_MONOTONIC_COARSE          6
322 #define CLOCK_BOOTTIME                  7
323 #define CLOCK_REALTIME_ALARM            8
324 #define CLOCK_BOOTTIME_ALARM            9                                                                                                     

 

二、有关时间操作:

上面简单的介绍了表示内核时间的数据类型,接下来就是我们在实际中如何使用了。

首先介绍一个函数,该函数的作用是将秒转换为格林时间;

48 /*
 49  * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
 50  */
 51 void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
 52 {
 53         unsigned int month, year;
 54         int days;
 55 
 56         days = time / 86400;
 57         time -= (unsigned int) days * 86400;
 58 
 59         /* day of the week, 1970-01-01 was a Thursday */
 60         tm->tm_wday = (days + 4) % 7;
 61 
 62         year = 1970 + days / 365;
 63         days -= (year - 1970) * 365
 64                 + LEAPS_THRU_END_OF(year - 1)
 65                 - LEAPS_THRU_END_OF(1970 - 1);
 66         if (days < 0) {
 67                 year -= 1;
 68                 days += 365 + is_leap_year(year);
 69         }
 70         tm->tm_year = year - 1900;
 71         tm->tm_yday = days + 1;
 72 
 73         for (month = 0; month < 11; month++) {
 74                 int newdays;
 75 
 76                 newdays = days - rtc_month_days(month, year);
 77                 if (newdays < 0)
 78                         break;
 79                 days = newdays;
 80         }
 81         tm->tm_mon = month;
 82         tm->tm_mday = days + 1;
 83 
 84         tm->tm_hour = time / 3600;
 85         time -= tm->tm_hour * 3600;
 86         tm->tm_min = time / 60;
 87         tm->tm_sec = time - tm->tm_min * 60;
 88 
 89         tm->tm_isdst = 0;
 90 }
 91 EXPORT_SYMBOL(rtc_time_to_tm);

获得当前系统的实际时间:

struct timespec ts;

struct rtc_time tm;

getnstimeofday(&ts);//获取当前系统的秒;

rtc_time_to_tm(ts.tv_sec, &tm);//将系统的秒转换为系统的格林时间;

pr_info("%d-%02d-%02d %02d:%02d:%02d\n",

                  tm.tm_year + 1900, tm.tm_mon +1, tm.tm_mday,

                   tm.tm_hour, tm.tm_min, tm.tm_sec);

 

 

posted on 2013-06-03 19:49  metootxy  阅读(6028)  评论(0编辑  收藏  举报