Annotation of sys/kern/clock_subr.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: clock_subr.c,v 1.2 2006/11/14 18:00:27 jmc Exp $ */
2: /* $NetBSD: clock_subr.c,v 1.3 1997/03/15 18:11:16 is Exp $ */
3:
4: /*
5: * Copyright (c) 1988 University of Utah.
6: * Copyright (c) 1982, 1990, 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * the Systems Programming Group of the University of Utah Computer
11: * Science Department.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * from: Utah $Hdr: clock.c 1.18 91/01/21$
38: *
39: * @(#)clock.c 8.2 (Berkeley) 1/12/94
40: */
41:
42: /*
43: * Generic routines to convert between a POSIX date
44: * (seconds since 1/1/1970) and yr/mo/day/hr/min/sec
45: * Derived from arch/hp300/hp300/clock.c
46: */
47:
48: #include <sys/types.h>
49: #include <sys/systm.h>
50:
51: #include <dev/clock_subr.h>
52:
53: static inline int leapyear(int year);
54: #define FEBRUARY 2
55: #define days_in_year(a) (leapyear(a) ? 366 : 365)
56: #define days_in_month(a) (month_days[(a) - 1])
57:
58: static const int month_days[12] = {
59: 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
60: };
61:
62: /*
63: * This inline avoids some unnecessary modulo operations
64: * as compared with the usual macro:
65: * ( ((year % 4) == 0 &&
66: * (year % 100) != 0) ||
67: * ((year % 400) == 0) )
68: * It is otherwise equivalent.
69: */
70: static inline int
71: leapyear(int year)
72: {
73: int rv = 0;
74:
75: if ((year & 3) == 0) {
76: rv = 1;
77: if ((year % 100) == 0) {
78: rv = 0;
79: if ((year % 400) == 0)
80: rv = 1;
81: }
82: }
83: return (rv);
84: }
85:
86: time_t
87: clock_ymdhms_to_secs(struct clock_ymdhms *dt)
88: {
89: time_t secs;
90: int i, year, days;
91:
92: year = dt->dt_year;
93:
94: /*
95: * Compute days since start of time.
96: * First from years, then from months.
97: */
98: days = 0;
99: for (i = POSIX_BASE_YEAR; i < year; i++)
100: days += days_in_year(i);
101: if (leapyear(year) && dt->dt_mon > FEBRUARY)
102: days++;
103:
104: /* Months */
105: for (i = 1; i < dt->dt_mon; i++)
106: days += days_in_month(i);
107: days += (dt->dt_day - 1);
108:
109: /* Add hours, minutes, seconds. */
110: secs = ((days
111: * 24 + dt->dt_hour)
112: * 60 + dt->dt_min)
113: * 60 + dt->dt_sec;
114:
115: return (secs);
116: }
117:
118: /* This function uses a copy of month_days[] */
119: #undef days_in_month
120: #define days_in_month(a) (mthdays[(a) - 1])
121:
122: void
123: clock_secs_to_ymdhms(time_t secs, struct clock_ymdhms *dt)
124: {
125: int mthdays[12];
126: int i, days;
127: int rsec; /* remainder seconds */
128:
129: bcopy(month_days, mthdays, sizeof(mthdays));
130:
131: days = secs / SECDAY;
132: rsec = secs % SECDAY;
133:
134: /* Day of week (Note: 1/1/1970 was a Thursday) */
135: dt->dt_wday = (days + 4) % 7;
136:
137: /* Subtract out whole years, counting them in i. */
138: for (i = POSIX_BASE_YEAR; days >= days_in_year(i); i++)
139: days -= days_in_year(i);
140: dt->dt_year = i;
141:
142: /* Subtract out whole months, counting them in i. */
143: if (leapyear(i))
144: days_in_month(FEBRUARY) = 29;
145: for (i = 1; days >= days_in_month(i); i++)
146: days -= days_in_month(i);
147: dt->dt_mon = i;
148:
149: /* Days are what is left over (+1) from all that. */
150: dt->dt_day = days + 1;
151:
152: /* Hours, minutes, seconds are easy */
153: dt->dt_hour = rsec / 3600;
154: rsec = rsec % 3600;
155: dt->dt_min = rsec / 60;
156: rsec = rsec % 60;
157: dt->dt_sec = rsec;
158: }
CVSweb