source: vendor/emx/current/src/os2/time.c

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 6.2 KB
Line 
1/* time.c -- Time and date
2 Copyright (c) 1994-1995 by Eberhard Mattes
3
4This file is part of emx.
5
6emx is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11emx is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with emx; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.
20
21As special exception, emx.dll can be distributed without source code
22unless it has been changed. If you modify emx.dll, this exception
23no longer applies and you must remove this paragraph from all source
24files for emx.dll. */
25
26
27#define INCL_DOSMISC
28#include <os2emx.h>
29#include "emxdll.h"
30#include <limits.h>
31#include <sys/timeb.h>
32#include <sys/time.h>
33
34
35/* Day number, relative to 01-Jan-1970, of 01-Jan for the years 1970
36 through 2106 */
37
38static ULONG const year_table[] =
39{
40 0, 365, 730, 1096, 1461, 1826, 2191, 2557, 2922, 3287, 3652, 4018,
41 4383, 4748, 5113, 5479, 5844, 6209, 6574, 6940, 7305, 7670, 8035,
42 8401, 8766, 9131, 9496, 9862, 10227, 10592, 10957, 11323, 11688,
43 12053, 12418, 12784, 13149, 13514, 13879, 14245, 14610, 14975,
44 15340, 15706, 16071, 16436, 16801, 17167, 17532, 17897, 18262,
45 18628, 18993, 19358, 19723, 20089, 20454, 20819, 21184, 21550,
46 21915, 22280, 22645, 23011, 23376, 23741, 24106, 24472, 24837,
47 25202, 25567, 25933, 26298, 26663, 27028, 27394, 27759, 28124,
48 28489, 28855, 29220, 29585, 29950, 30316, 30681, 31046, 31411,
49 31777, 32142, 32507, 32872, 33238, 33603, 33968, 34333, 34699,
50 35064, 35429, 35794, 36160, 36525, 36890, 37255, 37621, 37986,
51 38351, 38716, 39082, 39447, 39812, 40177, 40543, 40908, 41273,
52 41638, 42004, 42369, 42734, 43099, 43465, 43830, 44195, 44560,
53 44926, 45291, 45656, 46021, 46387, 46752, 47117, 47482, 47847,
54 48212, 48577, 48942, 49308, 49673, ULONG_MAX
55};
56
57/* Day number, relative to 01-Jan, of day 01 for January through
58 December. */
59
60static ULONG const month_table_non_leap[] =
61 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, ULONG_MAX};
62
63static ULONG const month_table_leap[] =
64 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, ULONG_MAX};
65
66
67/* Convert a my_datetime structure to Unix time format. */
68
69static time_t time2unix (const struct my_datetime *src)
70{
71 ULONG t, y;
72
73 if (src->day < 1 || src->day > 31 || src->month < 1 || src->month > 12
74 || src->year < 1970 || src->year > 2105
75 || src->seconds >= 60 || src->minutes >= 60 || src->hours >= 24)
76 return 0;
77
78 t = src->year * 365 + (src->month - 1) * 31 + src->day;
79 if (src->month <= 2)
80 {
81 /* Jan and Feb. */
82 y = src->year - 1;
83 }
84 else
85 {
86 /* Mar through Dec. */
87 y = src->year;
88 t -= (4 * src->month + 23) / 10;
89 }
90 t += y / 4;
91 t -= (3 * (y / 100 + 1)) / 4;
92 t -= 719528; /* 01-Jan-1970 */
93 return ((t * 24 + src->hours) * 60 + src->minutes) * 60 + src->seconds;
94}
95
96
97/* Return 1 if Y is a leap year, return 0 otherwise. */
98
99static int leap_year (ULONG y)
100{
101 if (y % 4 != 0)
102 return 0;
103 else if (y % 100 != 0)
104 return 1;
105 else if (y % 400 != 0)
106 return 0;
107 else
108 return 1;
109}
110
111
112/* Convert a Unix time value to a my_datetime structure. */
113
114void unix2time (struct my_datetime *dst, ULONG t)
115{
116 ULONG lo, hi, i;
117 const ULONG *p;
118
119 dst->seconds = t % 60; t /= 60;
120 dst->minutes = t % 60; t /= 60;
121 dst->hours = t % 24; t /= 24;
122
123 /* Find an i such that year_table[i] <= t < year_table[i+1]. */
124
125 lo = 0; hi = sizeof (year_table) / sizeof (year_table[0]) - 2;
126 for (;;)
127 {
128 i = (lo + hi) / 2;
129 if (year_table[i] > (int)t)
130 hi = i - 1;
131 else if (year_table[i+1] <= (int)t)
132 lo = i + 1;
133 else
134 break;
135 }
136 dst->year = i + 1970;
137 t -= year_table[i];
138
139 p = (leap_year (dst->year) ? month_table_leap : month_table_non_leap);
140 for (i = 0; t >= p[i+1]; ++i)
141 ;
142 dst->month = i + 1;
143 dst->day = t - p[i] + 1;
144}
145
146
147/* Get current time and store it in Unix format to the TIMEB structure
148 pointed to by DST. */
149
150void do_ftime (struct timeb *dst)
151{
152 DATETIME dt;
153 struct my_datetime tmp;
154
155 DosGetDateTime (&dt);
156 tmp.seconds = dt.seconds;
157 tmp.minutes = dt.minutes;
158 tmp.hours = dt.hours;
159 tmp.day = dt.day;
160 tmp.month = dt.month;
161 tmp.year = dt.year;
162 dst->time = time2unix (&tmp);
163 dst->dstflag = 0;
164 dst->millitm = dt.hundredths * 10;
165 dst->timezone = dt.timezone; /* This will be overridden by ftime() */
166}
167
168
169/* Convert packed time and date to Unix format. */
170
171ULONG packed2unix (FDATE date, FTIME time)
172{
173 struct my_datetime tmp;
174
175 tmp.seconds = time.twosecs * 2;
176 tmp.minutes = time.minutes;
177 tmp.hours = time.hours;
178 tmp.day = date.day;
179 tmp.month = date.month;
180 tmp.year = date.year + 1980;
181 return time2unix (&tmp);
182}
183
184
185/* Return the number of 1/100 seconds elapsed since the process has
186 been started.
187
188 This function no longer tries to use QSV_TIME_LOW and QSV_TIME_HIGH
189 to increase the time before the return value wraps around. Now, it
190 will wrap around after 49 days. */
191
192unsigned long long get_clock (int init_flag)
193{
194 ULONG ms;
195 static ULONG clock0_ms;
196
197 ms = querysysinfo (QSV_MS_COUNT);
198 if (init_flag)
199 {
200 clock0_ms = ms;
201 return 0;
202 }
203 else
204 return (ms - clock0_ms) / 10;
205}
206
207
208int do_settime (const struct timeval *tp, int *errnop)
209{
210 DATETIME dt;
211 struct my_datetime mdt;
212 ULONG rc;
213
214 /* Preserve the value of DATETIME.timezone. */
215
216 rc = DosGetDateTime (&dt);
217 if (rc != 0)
218 {
219 *errnop = set_error (rc);
220 return -1;
221 }
222
223 unix2time (&mdt, tp->tv_sec + tp->tv_usec / 1000000);
224
225 /* Keep dt.timezone! */
226
227 dt.day = mdt.day;
228 dt.month = mdt.month;
229 dt.year = mdt.year;
230 dt.weekday = 0;
231
232 dt.hours = mdt.hours;
233 dt.minutes = mdt.minutes;
234 dt.seconds = mdt.seconds;
235 dt.hundredths = (tp->tv_usec / 10000) % 100;
236
237 rc = DosSetDateTime (&dt);
238 if (rc != 0)
239 {
240 *errnop = set_error (rc);
241 return -1;
242 }
243 *errnop = 0;
244 return 0;
245}
Note: See TracBrowser for help on using the repository browser.