Annotation of embedaddon/php/ext/date/lib/dow.c, revision 1.1.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>