代码改变世界

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