關(guān)于kernel_mktime 函數(shù)詳解
kernel_mktime函數(shù)詳解
這幾天在linux內(nèi)核QQ群中看到很多成員都在詢問linux0.11版中kernel_mktime函數(shù)原理,看來大家都對(duì)linux內(nèi)核很感興趣??!下面詳細(xì)的講解其原理以供大家參考。
以下是kernel_mktime函數(shù)原碼:
/***這段代碼理解起來因該沒問題***/
#define MINUTE 60
#define HOUR (60*MINUTE)
#define DAY (24*HOUR)
#define YEAR (365*DAY)
staticint month[12] = {
???????? 0,
???????? DAY*(31),
???????? DAY*(31+29), ? ? //注意:此行表示默認(rèn)當(dāng)年是閏年,閏年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)
};
/***注意:此函數(shù)只能正確表示1970到1999年的時(shí)間,因?yàn)閠m->tm_year只用兩位數(shù)用表年份***/
longkernel_mktime(struct tm * tm)
{
? ? ? ? ?longres;
???????? intyear;
???????? year= tm->tm_year - 70;????????????????? //計(jì)算1970年到當(dāng)年的年數(shù)
/* magic offsets (y+1) needed to getleapyears right.*/
/* 下面這句含意:YEAR*year 表示這些年總供經(jīng)過的秒數(shù),DAY*((year+1)/4表示這些年中有多少個(gè)閏年,每個(gè)閏都需多加一天的秒數(shù)。Year+1表示計(jì)算閏年時(shí)從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 */
/*下面這句的目的主要是判斷當(dāng)年是否為閏年,如果不是需減掉一天的秒數(shù)(因?yàn)閙onth全局變量中默認(rèn)二月份有29天)。這里判斷當(dāng)年是否為閏年并沒有用閏年算法(參見下面的閏年算法),每4年就會(huì)出去一次閏年,如:1970年不是閏年,1971年不是,1972年是,1973年不是,1974年不是,1975年不是,1976年是閏年…。大家有沒有注意到1972,1976,1980這些閏年的規(guī)律,閏年的后兩位+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整除。