linux0.12-8-5-mktime.c

该文详细介绍了Linux内核中的kernel_mktime()函数,该函数用于计算从1970年1月1日到指定日期的秒数。代码注释解释了如何处理闰年和月份的天数,以及内核为何需要自定义此函数而非使用标准库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[313页]

8-5 mktime.c 程序

8-5-1 功能描述

该程序只有一个函数kernel_mktime(),仅供内核使用。计算从1970年1月1日0时起到开机当日经过的秒数(日历时间),作为开机时间。该函数与标准C库中提供的mktime()函数的功能完全一样,都是将tm结构表示的时间转换为UNIX日历时间。但是由于内核不是普通程序,不能调用开发环境库中的函数,因此这里就必须自己专门编写一个了。

8-5-2 代码注释

/*
 *  linux/kernel/mktime.c
 *
 *  (C) 1991  Linus Torvalds
 */

#include <time.h>//时间头文件,定义了标准时间数据结构tm和一些处理时间函数原型。

/*
这不是库函数,它仅供内核使用。因此我们不关心小于1970年的年份等,但假定一起均很正常。同样,时间区域TZ问题也先忽略。我们只是尽可能简单地处理问题。最好能找到一些公开的库函数(尽管我认为minix的时间函数时公开的)。
另外,我恨那个设置1970年开始的人 - 难道他们就不能选择从一个闰年开始?
我恨格里高利历、罗马教皇、主教,我什么都不在乎。我是个脾气暴躁的人。
 */

#define MINUTE 60					//1分钟的秒数
#define HOUR (60*MINUTE)			//1小时的秒数
#define DAY (24*HOUR)				//1天的秒数
#define YEAR (365*DAY)				//1年的秒数

/* 有趣的是我们考虑进了闰年 */
//下面以年为界限,定义了每个月开始时的秒数时间。
static int month[12] = {
	0,
	DAY*(31),
	DAY*(31+29),
	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年1月1日0时起到开机当日经过的秒数,作为开机时间。
//参数tm中各字段已经在init/main.c中被赋值,信息取自CMOS。
long kernel_mktime(struct tm * tm)
{
	long res;
	int year;
//首先计算1970年到现在经过的年数。因为是2位表示方式,所以会有2000年问题。
//解决办法:if(tm->tm_year<70)ti->tm_year += 100;
//由于UNIX计年份是从1970年算起。到1972年就是一个闰年,因此过3年(70,71,72)就是
//第1个闰年,从1970年开始的闰年数计算方式=1+(y-3)/4=(y+1)/4。
//因为我们的month数组的二月是有29天的,如果当年不是闰年且大于1月份,减去一天的秒数时间。
	year = tm->tm_year - 70;
/* 为了获得正确的闰年数,这里需要这样一个魔幻值(y+1)*/
	res = YEAR*year + DAY*((year+1)/4);
	res += month[tm->tm_mon];
/* 以及(y+2)。如果(y+2)不是闰年,那么我们就必须进行调整(减去一天的秒数时间)。 */
	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;
	return res;
}

8-5-3 闰年的计算方法

闰年的基本计算方法是:
如果y能被4整除且不能被100整除,或者能被400整除,则y是闰年。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值