Nginx 中ngx_gmtime函数小析
2011-11-30 14:26 cdamo 阅读(854) 评论(0) 编辑 收藏 举报Nginx 中ngx_gmtime函数小析
最近开始看nginx原码,从main()函数开始,看到ngx_gmtime()函数时,发现有些地方看不明白.
void
ngx_gmtime(time_t t, ngx_tm_t *tp)
{
ngx_int_t yday;
ngx_uint_t n, sec, min, hour, mday, mon, year, wday, days, leap;
/* the calculation is valid for positive time_t only */
n = (ngx_uint_t) t;
days = n / 86400;
/* Jaunary 1, 1970 was Thursday */
wday = (4 + days) % 7;
n %= 86400;
hour = n / 3600;
n %= 3600;
min = n / 60;
sec = n % 60;
….. (这里处理 1970.1.1后的当时秒数的days ,wday hour min sec 数据)
/*
* the algorithm based on Gauss' formula,
* see src/http/ngx_http_parse_time.c
*/
/* days since March 1, 1 BC */
days = days - (31 + 28) + 719527; (这里比较疑惑 719527 是怎么来的?) 经过查找资料才明白 719527 是从公元前1年3月1日到1970年3月1日的天数. 不信的朋友可以算算.
1970*365 + 1970/4(被4整除的润年的天数)- 1970/100(扣掉被100整除的天数)+1970/400(能被400整除的润年的天数) =719527(天)
//(365 * 400 + 100 - 4 + 1) 为400年总的天数
year = (days + 2) * 400 / (365 * 400 + 100 - 4 + 1); //计算年份
yday = days - (365 * year + year / 4 - year / 100 + year / 400);
if (yday < 0) {
leap = (year % 4 == 0) && (year % 100 || (year % 400 == 0));
yday = 365 + leap + yday;
year--;
}
在本算法中采用了高斯算法, 从3月1日开始算 这样就省去了2月份是28天还是29天的麻烦. 有问题的就是第一个月, 把1,2月放到上一年的末尾,改变后的月份就变成如下形式
月份 |
月份 |
天数 |
间隔 |
1 |
3 |
30 |
30 |
2 |
4 |
31 |
61 |
3 |
5 |
30 |
91 |
4 |
6 |
31 |
122 |
5 |
7 |
30 |
152 |
6 |
8 |
31 |
183 |
7 |
9 |
31 |
214 |
8 |
10 |
30 |
244 |
9 |
11 |
31 |
275 |
10 |
12 |
30 |
305 |
11 |
1 |
31 |
336 |
12 |
2 |
31 |
367 |
mon = (yday + 31) * 10 / 306;
/* the Gauss' formula that evaluates days before the month */
mday = yday - (367 * mon / 12 - 30) + 1;
至此 306 , 367这些数字都清楚它的由来了.
参考资料: http://hi.baidu.com/jiazheng2222/blog/item/13ed39cd55f20e0601e92817.html