Annotation of embedaddon/php/ext/date/lib/dow.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:    | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Derick Rethans <derick@derickrethans.nl>                    |
                     16:    +----------------------------------------------------------------------+
                     17:  */
                     18: 
1.1.1.2   misho      19: /* $Id$ */
1.1       misho      20: 
                     21: #include "timelib.h"
                     22: 
                     23: static int m_table_common[13] = { -1, 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 }; /* 1 = jan */
                     24: static int m_table_leap[13] =   { -1, 6, 2, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 }; /* 1 = jan */
                     25: 
                     26: static timelib_sll century_value(timelib_sll j)
                     27: {
                     28:        timelib_sll i = j - 17;
                     29:        timelib_sll c = (4 - i * 2 + (i + 1) / 4) % 7;
                     30: 
                     31:        return c < 0 ? c + 7 : c;
                     32: }
                     33: 
                     34: static timelib_sll timelib_day_of_week_ex(timelib_sll y, timelib_sll m, timelib_sll d, int iso)
                     35: {
                     36:        timelib_sll c1, y1, m1, dow;
                     37: 
                     38:        /* Only valid for Gregorian calendar, commented out as we don't handle
                     39:         * julian calendar. We just return the 'wrong' day of week to be
                     40:         * consistent.
                     41:        if (y < 1753) {
                     42:                return -1;
                     43:        } */
                     44:        c1 = century_value(y / 100);
                     45:        y1 = (y % 100);
                     46:        m1 = timelib_is_leap(y) ? m_table_leap[m] : m_table_common[m];
                     47:        dow = (c1 + y1 + m1 + (y1 / 4) + d) % 7;
                     48:        if (iso) {
                     49:                if (dow == 0) {
                     50:                        dow = 7;
                     51:                }
                     52:        }
                     53:        return dow;
                     54: }
                     55: 
                     56: timelib_sll timelib_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d)
                     57: {
                     58:        return timelib_day_of_week_ex(y, m, d, 0);
                     59: }
                     60: 
                     61: timelib_sll timelib_iso_day_of_week(timelib_sll y, timelib_sll m, timelib_sll d)
                     62: {
                     63:        return timelib_day_of_week_ex(y, m, d, 1);
                     64: }
                     65: 
                     66:                                 /*     jan  feb  mar  apr  may  jun  jul  aug  sep  oct  nov  dec */
                     67: static int d_table_common[13]  = {  0,   0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334 };
                     68: static int d_table_leap[13]    = {  0,   0,  31,  60,  91, 121, 152, 182, 213, 244, 274, 305, 335 };
                     69: static int ml_table_common[13] = {  0,  31,  28,  31,  30,  31,  30,  31,  31,  30,  31,  30,  31 };
                     70: static int ml_table_leap[13]   = {  0,  31,  29,  31,  30,  31,  30,  31,  31,  30,  31,  30,  31 };
                     71: 
                     72: timelib_sll timelib_day_of_year(timelib_sll y, timelib_sll m, timelib_sll d)
                     73: {
                     74:        return (timelib_is_leap(y) ? d_table_leap[m] : d_table_common[m]) + d - 1;
                     75: }
                     76: 
                     77: timelib_sll timelib_days_in_month(timelib_sll y, timelib_sll m)
                     78: {
                     79:        return timelib_is_leap(y) ? ml_table_leap[m] : ml_table_common[m];
                     80: }
                     81: 
                     82: void timelib_isoweek_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iw, timelib_sll *iy)
                     83: {
                     84:        int y_leap, prev_y_leap, doy, jan1weekday, weekday;
                     85: 
                     86:        y_leap = timelib_is_leap(y);
                     87:        prev_y_leap = timelib_is_leap(y-1);
                     88:        doy = timelib_day_of_year(y, m, d) + 1;
                     89:        if (y_leap && m > 2) {
                     90:                doy++;
                     91:        }
                     92:        jan1weekday = timelib_day_of_week(y, 1, 1);
                     93:        weekday = timelib_day_of_week(y, m, d);
                     94:        if (weekday == 0) weekday = 7;
                     95:        if (jan1weekday == 0) jan1weekday = 7;
                     96:        /* Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53 */
                     97:        if (doy <= (8 - jan1weekday) && jan1weekday > 4) {
                     98:                *iy = y - 1;
                     99:                if (jan1weekday == 5 || (jan1weekday == 6 && prev_y_leap)) {
                    100:                        *iw = 53;
                    101:                } else {
                    102:                        *iw = 52;
                    103:                }
                    104:        } else {
                    105:                *iy = y;
                    106:        }
                    107:        /* 8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1 */
                    108:        if (*iy == y) {
                    109:                int i;
                    110: 
                    111:                i = y_leap ? 366 : 365;
                    112:                if ((i - (doy - y_leap)) < (4 - weekday)) {
                    113:                        *iy = y + 1;
                    114:                        *iw = 1;
                    115:                        return;
                    116:                }
                    117:        }
                    118:        /* 9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53 */
                    119:        if (*iy == y) {
                    120:                int j;
                    121: 
                    122:                j = doy + (7 - weekday) + (jan1weekday - 1);
                    123:                *iw = j / 7;
                    124:                if (jan1weekday > 4) {
                    125:                        *iw -= 1;
                    126:                }
                    127:        }
                    128: }
                    129: 
                    130: timelib_sll timelib_daynr_from_weeknr(timelib_sll y, timelib_sll w, timelib_sll d)
                    131: {
                    132:        timelib_sll dow, day;
                    133:        
                    134:        /* Figure out the dayofweek for y-1-1 */
                    135:        dow = timelib_day_of_week(y, 1, 1);
                    136:        /* then use that to figure out the offset for day 1 of week 1 */
                    137:        day = 0 - (dow > 4 ? dow - 7 : dow);
                    138: 
                    139:        /* Add weeks and days */
                    140:        return day + ((w - 1) * 7) + d;
                    141: }
                    142: 
                    143: int timelib_valid_time(timelib_sll h, timelib_sll i, timelib_sll s)
                    144: {
                    145:        if (h < 0 || h > 23 || i < 0 || i > 59 || s < 0 || s > 59) {
                    146:                return 0;
                    147:        }
                    148:        return 1;
                    149: }
                    150: 
                    151: int timelib_valid_date(timelib_sll y, timelib_sll m, timelib_sll d)
                    152: {
                    153:        if (m < 1 || m > 12 || d < 1 || d > timelib_days_in_month(y, m)) {
                    154:                return 0;
                    155:        }
                    156:        return 1;
                    157: }
                    158: #if 0
                    159: int main(void)
                    160: {
                    161:        printf("dow = %d\n", timelib_day_of_week(1978, 12, 22)); /* 5 */
                    162:        printf("dow = %d\n", timelib_day_of_week(2005,  2, 19)); /* 6 */
                    163: }
                    164: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>