Annotation of embedaddon/php/ext/date/lib/dow.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2010 The PHP Group |
! 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:
! 19: /* $Id: dow.c 293036 2010-01-03 09:23:27Z sebastian $ */
! 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>