kernel_mktime函数详解
这几天在linux内核QQ群中看到很多成员都在询问linux0.11版中kernel_mktime函数原理,看来大家都对linux内核很感兴趣啊!下面详细的讲解其原理以供大家参考。
以下是kernel_mktime函数原码:
/***这段代码理解起来因该没问题***/
#define MINUTE 60
#define HOUR (60*MINUTE)
#define DAY (24*HOUR)
#define YEAR (365*DAY)
staticint month[12] = {
0,
DAY*(31),
DAY*(31+29), //注意:此行表示默认当年是闰年,闰年2月份为29天,平年为28天
DAY*(31+29+31),
DAY*(31+29+31+30),
DAY*(31+29+31+30+31),
DAY*(31+29+31+30+31+30),
DAY*(31+29+31+30+31+30+31),
DAY*(31+29+31+30+31+30+31+31),
DAY*(31+29+31+30+31+30+31+31+30),
DAY*(31+29+31+30+31+30+31+31+30+31),
DAY*(31+29+31+30+31+30+31+31+30+31+30)
};
/***注意:此函数只能正确表示1970到1999年的时间,因为tm->tm_year只用两位数用表年份***/
longkernel_mktime(struct tm * tm)
{
longres;
intyear;
year= tm->tm_year - 70; //计算1970年到当年的年数
/* magic offsets (y+1) needed to getleapyears right.*/
/* 下面这句含意:YEAR*year 表示这些年总供经过的秒数,DAY*((year+1)/4表示这些年中有多少个闰年,每个闰都需多加一天的秒数。Year+1表示计算闰年时从1970年算起*/
res= YEAR*year + DAY*((year+1)/4);
res+= month[tm->tm_mon];
/* and (y+2) here. If it wasn't aleap-year, we have to adjust */
/*下面这句的目的主要是判断当年是否为闰年,如果不是需减掉一天的秒数(因为month全局变量中默认二月份有29天)。这里判断当年是否为闰年并没有用闰年算法(参见下面的闰年算法),每4年就会出去一次闰年,如:1970年不是闰年,1971年不是,1972年是,1973年不是,1974年不是,1975年不是,1976年是闰年…。大家有没有注意到1972,1976,1980这些闰年的规律,闰年的后两位+2都能被4整除。*/
if(tm->tm_mon>1 && ((year+2)%4))
res-= DAY;
res+= DAY*(tm->tm_mday-1);
res+= HOUR*tm->tm_hour;
res+= MINUTE*tm->tm_min;
res+= tm->tm_sec;
returnres;
}
闰年算法:如果年份能被4整除但不能被100整除,或者年份能被400整除。