下文中会用到一些公式,比如:empirical formula
和Gauss' formula
等。主要思想取自 Nginx 的时间管理机制中。
如果已知毫秒数为:
unsigned int msec_total;
那么秒数和余毫秒数为:
unsigned int sec_total = msec_total / 1000;
unsigned int msec = msec_total % 1000; /* What we want */
分钟数和余秒数为:
unsigned int min_total = sec_total / 60;
unsigned int sec = sec_total % 60;
小时数和余分钟数为:
unsigned int hour_total = min_total / 60;
unsigned int min = min_total % 60;
余小时数为:
unsigned int hour = hour_total % 24;
剩下的内容非常重要。
unsigned int day_total = hour_total / 24;
day_total = day_total - (31 + 28) + 719527; /* days since March 1, 1 BC */
什么是闰年?有如下几类:
所以总年数是:
/* 总年数 */
year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1);
还要继续知道整年的余天:
/* yday是整年的余天 */
yday = days - (365 * year + year / 4 - year / 100 + year / 400);
/* 如果余天小于0,说明年数应该减一 */
if (yday < 0) {
/* 可以被4整除,且不可以被100整除,且可以被400整除 */
leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0));
/* 加当年的年数补差值 */
yday = 365 + leap + yday;
year--;
}
具体的解释看注释。
转载请注明来自柳大的CSDN博客:Blog.CSDN.net
这里用到empirical formula
和Gauss' formula
。
/*
* The empirical formula that maps "yday" to month.
* There are at least 10 variants, some of them are:
* mon = (yday + 31) * 15 / 459
* mon = (yday + 31) * 17 / 520
* mon = (yday + 31) * 20 / 612
*/
/* 30.6 为平均每月天数 */
mon = (yday + 31) * 10 / 306;
/* the Gauss' formula that evaluates days before the month */
mday = yday - (367 * mon / 12 - 30) + 1;
if (yday >= 306) {
year++;
mon -= 10;
/*
* there is no "yday" in Win32 SYSTEMTIME
*
* yday -= 306;
*/
} else {
mon += 2;
/*
* there is no "yday" in Win32 SYSTEMTIME
*
* yday += 31 + 28 + leap;
*/
}
wday = (4 + days) % 7; /* 今儿是星期几?注意,1970年1年1日为星期四 */
msec; /* 毫秒 */
sec; /* 秒 */
min; /* 分 */
hour; /* 小时 */
mday; /* 日 */
mon; /* 月 */
year; /* 年 */
wday; /* 星期 */
闰秒是人为加入的,计算机中如何表示?什么时候插入闰秒,是由人来决定的,只不过原因是可探究的,但依然无法用公式或程序来计算。
是否加入闰秒由位于巴黎的国际地球自转和参考座标系统服务决定,在格里历的每年的6月或12月的最后一天的最后一分钟进行跳秒或不跳秒,也就是说每年的这两个一分钟并不就是等于60秒,而是在60秒上下变化。
全球定位系统服务界面委员会在得克萨斯州沃斯堡举行的第47届会议中宣布,他们已经邮寄出停止闰秒的表决案。这项表决案的计划是[1]:
-
转载请注明来自柳大的CSDN博客:Blog.CSDN.net
-