1 /*-------------------------------------------------------------------------
4 * implements DATE and TIME data types specified in SQL-92 standard
6 * Copyright (c) 1994-5, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/datetimes.c,v 1.8 1997/01/26 15:31:12 scrappy Exp $
12 *-------------------------------------------------------------------------
14 #include <stdio.h> /* for sprintf() */
18 #include <miscadmin.h>
19 #include <utils/builtins.h>
20 #include <utils/datetime.h>
22 static int day_tab[2][12] = {
23 {31,28,31,30,31,30,31,31,30,31,30,31},
24 {31,29,31,30,31,30,31,31,30,31,30,31} };
30 (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0);
33 /*****************************************************************************
35 *****************************************************************************/
38 date_in(char *datestr)
42 DateADT *date = (DateADT*)&result;
45 # ifdef USE_SHORT_YEAR
46 # define CHECK_DATE_LEN(datestr) (strlen(datestr) >= 8)
48 # define CHECK_DATE_LEN(datestr) (strlen(datestr) == 10)
49 # endif /* USE_SHORT_YEAR */
51 # define CHECK_DATE_LEN(datestr) 1
54 if (EuroDates == 1) { /* Expect european format dates */
55 if (!CHECK_DATE_LEN(datestr) ||
56 sscanf(datestr, "%d%*c%d%*c%d", &d, &m, &y) != 3) {
57 elog(WARN, "date_in: date \"%s\" not of the form dd-mm-yyyy",
61 if (!CHECK_DATE_LEN(datestr) ||
62 sscanf(datestr, "%d%*c%d%*c%d", &m, &d, &y) != 3) {
63 elog(WARN, "date_in: date \"%s\" not of the form mm-dd-yyyy",
67 if (y < 0 || y > 32767)
68 elog(WARN, "date_in: year must be limited to values 0 through 32767 in \"%s\"", datestr);
70 elog(WARN, "date_in: month must be limited to values 1 through 12 in \"%s\"", datestr);
71 if (d < 1 || d > day_tab[isleap(y)][m-1])
72 elog(WARN, "date_in: day must be limited to values 1 through %d in \"%s\"",
73 day_tab[isleap(y)][m-1], datestr);
77 y += 1900; /* hack! */
78 #endif /* USE_SHORT_YEAR */
87 date_out(int4 dateVal)
89 char *datestr = palloc(11);
93 /* DateADT is a structure that happens to be four bytes long,
94 trust me on this.... */
95 date = (DateADT*)&dateStore;
98 if (EuroDates == 1) /* Output european format dates */
99 sprintf(datestr, "%02d-%02d-%04d",
100 (int)date->day, (int)date->month, (int)date->year);
102 sprintf(datestr, "%02d-%02d-%04d",
103 (int)date->month, (int)date->day, (int)date->year);
110 date_eq(int4 dateVal1, int4 dateVal2)
112 int4 dateStore1 = dateVal1;
113 int4 dateStore2 = dateVal2;
114 DateADT *date1, *date2;
116 date1 = (DateADT*)&dateStore1;
117 date2 = (DateADT*)&dateStore2;
119 return (date1->day==date2->day &&
120 date1->month==date2->month &&
121 date1->year==date2->year);
125 date_ne(int4 dateVal1, int4 dateVal2)
127 int4 dateStore1 = dateVal1;
128 int4 dateStore2 = dateVal2;
129 DateADT *date1, *date2;
131 date1 = (DateADT*)&dateStore1;
132 date2 = (DateADT*)&dateStore2;
134 return (date1->day!=date2->day || date1->month!=date2->month ||
135 date1->year!=date2->year);
139 date_lt(int4 dateVal1, int4 dateVal2)
141 int4 dateStore1 = dateVal1;
142 int4 dateStore2 = dateVal2;
143 DateADT *date1, *date2;
145 date1 = (DateADT*)&dateStore1;
146 date2 = (DateADT*)&dateStore2;
148 if (date1->year!=date2->year)
149 return (date1->year<date2->year);
150 if (date1->month!=date2->month)
151 return (date1->month<date2->month);
152 return (date1->day<date2->day);
156 date_le(int4 dateVal1, int4 dateVal2)
159 int4 dateStore1 = dateVal1;
160 int4 dateStore2 = dateVal2;
161 DateADT *date1, *date2;
163 date1 = (DateADT*)&dateStore1;
164 date2 = (DateADT*)&dateStore2;
166 if (date1->year!=date2->year)
167 return (date1->year<=date2->year);
168 if (date1->month!=date2->month)
169 return (date1->month<=date2->month);
170 return (date1->day<=date2->day);
174 date_gt(int4 dateVal1, int4 dateVal2)
176 int4 dateStore1 = dateVal1;
177 int4 dateStore2 = dateVal2;
178 DateADT *date1, *date2;
180 date1 = (DateADT*)&dateStore1;
181 date2 = (DateADT*)&dateStore2;
184 if (date1->year!=date2->year)
185 return (date1->year>date2->year);
186 if (date1->month!=date2->month)
187 return (date1->month>date2->month);
188 return (date1->day>date2->day);
192 date_ge(int4 dateVal1, int4 dateVal2)
194 int4 dateStore1 = dateVal1;
195 int4 dateStore2 = dateVal2;
196 DateADT *date1, *date2;
198 date1 = (DateADT*)&dateStore1;
199 date2 = (DateADT*)&dateStore2;
201 if (date1->year!=date2->year)
202 return (date1->year>=date2->year);
203 if (date1->month!=date2->month)
204 return (date1->month>=date2->month);
205 return (date1->day>=date2->day);
209 date_cmp(int4 dateVal1, int4 dateVal2)
211 int4 dateStore1 = dateVal1;
212 int4 dateStore2 = dateVal2;
213 DateADT *date1, *date2;
215 date1 = (DateADT*)&dateStore1;
216 date2 = (DateADT*)&dateStore2;
218 if (date1->year!=date2->year)
219 return ((date1->year<date2->year) ? -1 : 1);
220 if (date1->month!=date2->month)
221 return ((date1->month<date2->month) ? -1 : 1);
222 if (date1->day!=date2->day)
223 return ((date1->day<date2->day) ? -1 : 1);
228 date_larger(int4 dateVal1, int4 dateVal2)
230 return (date_gt (dateVal1, dateVal2) ? dateVal1 : dateVal2);
234 date_smaller(int4 dateVal1, int4 dateVal2)
236 return (date_lt (dateVal1, dateVal2) ? dateVal1 : dateVal2);
239 /* Compute difference between two dates in days. */
241 date_mi(int4 dateVal1, int4 dateVal2)
243 DateADT *date1, *date2;
247 date1 = (DateADT *) &dateVal1;
248 date2 = (DateADT *) &dateVal2;
250 /* Sum number of days in each full year between date1 and date2. */
251 for (i = date1->year + 1; i < date2->year; ++i)
252 days += isleap (i) ? 366 : 365;
254 /* Add in number of days in each full month from date1 to end of
256 for (i = date1->month + 1; i <= 12; ++i)
257 days += day_tab[isleap (date1->year)][i - 1];
259 /* Add in number of days in each full month from start of year to
261 for (i = 1; i < date2->month; ++i)
262 days += day_tab[isleap (date2->year)][i - 1];
264 /* Add in number of days left in month for date1. */
265 days += day_tab[isleap (date1->year)][date1->month - 1] - date1->day;
267 /* Add in day of month of date2. */
273 /* Add a number of days to a date, giving a new date.
274 Must handle both positive and negative numbers of days. */
276 date_pli(int4 dateVal, int32 days)
278 DateADT *date1 = (DateADT *) &dateVal;
279 /* Use separate day variable because date1->day is a narrow type. */
280 int32 day = date1->day + days;
284 /* Loop as long as day has wrapped around end of month. */
285 while (day > day_tab[isleap (date1->year)][date1->month - 1])
287 day -= day_tab[isleap (date1->year)][date1->month - 1];
288 if (++date1->month > 12)
290 /* Month wrapped around. */
298 /* Loop as long as day has wrapped around beginning of month. */
301 /* Decrement month first, because a negative day number
302 should be held as relative to the previous month's end. */
303 if (--date1->month < 1)
305 /* Month wrapped around. */
310 day += day_tab[isleap (date1->year)][date1->month - 1];
318 /* Subtract a number of days from a date, giving a new date. */
320 date_mii(int4 dateVal, int32 days)
322 return (date_pli (dateVal, -days));
325 /*****************************************************************************
327 *****************************************************************************/
330 time_in(char *timestr)
336 if (sscanf(timestr, "%d%*c%d%*c%f", &h, &m, &sec) != 3) {
338 if (sscanf(timestr, "%d%*c%d", &h, &m) != 2) {
339 elog(WARN, "time_in: time \"%s\" not of the form hh:mm:ss",
345 elog(WARN, "time_in: hour must be limited to values 0 through 23 in \"%s\"", timestr);
347 elog(WARN, "time_in: minute must be limited to values 0 through 59 in \"%s\"", timestr);
348 if (sec < 0 || sec >= 60.0)
349 elog(WARN, "time_in: second must be limited to values 0 through 59.999 in \"%s\"", timestr);
351 time = (TimeADT*)palloc(sizeof(TimeADT));
359 time_out(TimeADT *time)
361 char *timestr = palloc(32);
365 if (time->sec == 0.0) {
366 sprintf(timestr, "%02d:%02d",
367 (int)time->hr, (int)time->min);
371 if (f == time->sec) {
372 sprintf(timestr, "%02d:%02d:%02d",
373 (int)time->hr, (int)time->min, n);
375 sprintf(timestr, "%02d:%02d:%09.6f",
376 (int)time->hr, (int)time->min, time->sec);
385 time_eq(TimeADT *time1, TimeADT *time2)
387 return (time1->sec==time2->sec && time1->min==time2->min &&
388 time1->hr==time2->hr);
392 time_ne(TimeADT *time1, TimeADT *time2)
394 return (time1->sec!=time2->sec || time1->min!=time2->min ||
395 time1->hr!=time2->hr);
399 time_lt(TimeADT *time1, TimeADT *time2)
401 if (time1->hr!=time2->hr)
402 return (time1->hr<time2->hr);
403 if (time1->min!=time2->min)
404 return (time1->min<time2->min);
405 return (time1->sec<time2->sec);
409 time_le(TimeADT *time1, TimeADT *time2)
411 if (time1->hr!=time2->hr)
412 return (time1->hr<=time2->hr);
413 if (time1->min!=time2->min)
414 return (time1->min<=time2->min);
415 return (time1->sec<=time2->sec);
419 time_gt(TimeADT *time1, TimeADT *time2)
421 if (time1->hr!=time2->hr)
422 return (time1->hr>time2->hr);
423 if (time1->min!=time2->min)
424 return (time1->min>time2->min);
425 return (time1->sec>time2->sec);
429 time_ge(TimeADT *time1, TimeADT *time2)
431 if (time1->hr!=time2->hr)
432 return (time1->hr>=time2->hr);
433 if (time1->min!=time2->min)
434 return (time1->min>=time2->min);
435 return (time1->sec>=time2->sec);
439 time_cmp(TimeADT *time1, TimeADT *time2)
441 if (time1->hr!=time2->hr)
442 return ((time1->hr<time2->hr) ? -1 : 1);
443 if (time1->min!=time2->min)
444 return ((time1->min<time2->min) ? -1 : 1);
445 if (time1->sec!=time2->sec)
446 return ((time1->sec<time2->sec) ? -1 : 1);
450 int32 /* RelativeTime */
451 int42reltime(int32 timevalue)