|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.49 2000/07/12 22:59:08 petere Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.50 2000/09/12 05:41:37 thomas Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
25 | 25 | #include "utils/nabstime.h"
|
26 | 26 |
|
27 | 27 |
|
28 |
| -static int date2tm(DateADT dateVal, int *tzp, struct tm * tm, |
29 |
| - double *fsec, char **tzn); |
30 |
| - |
31 |
| - |
32 | 28 | /*****************************************************************************
|
33 | 29 | * Date ADT
|
34 | 30 | *****************************************************************************/
|
@@ -230,15 +226,34 @@ date_timestamp(PG_FUNCTION_ARGS)
|
230 | 226 | Timestamp result;
|
231 | 227 | struct tm tt,
|
232 | 228 | *tm = &tt;
|
233 |
| - int tz; |
234 |
| - double fsec = 0; |
235 |
| - char *tzn; |
| 229 | + time_t utime; |
236 | 230 |
|
237 |
| - if (date2tm(dateVal, &tz, tm, &fsec, &tzn) != 0) |
238 |
| - elog(ERROR, "Unable to convert date to timestamp"); |
| 231 | + j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday)); |
239 | 232 |
|
240 |
| - if (tm2timestamp(tm, fsec, &tz, &result) != 0) |
241 |
| - elog(ERROR, "Timestamp out of range"); |
| 233 | + if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) |
| 234 | + { |
| 235 | +#ifdef USE_POSIX_TIME |
| 236 | + tm->tm_hour = 0; |
| 237 | + tm->tm_min = 0; |
| 238 | + tm->tm_sec = 0; |
| 239 | + tm->tm_isdst = -1; |
| 240 | + |
| 241 | + tm->tm_year -= 1900; |
| 242 | + tm->tm_mon -= 1; |
| 243 | + utime = mktime(tm); |
| 244 | + if (utime == -1) |
| 245 | + elog(ERROR, "Unable to convert date to tm"); |
| 246 | + |
| 247 | + result = utime + ((date2j(1970,1,1)-date2j(2000,1,1))*86400.0); |
| 248 | +#else /* !USE_POSIX_TIME */ |
| 249 | + result = dateVal*86400.0+CTimeZone; |
| 250 | +#endif |
| 251 | + } |
| 252 | + else |
| 253 | + { |
| 254 | + /* Outside of range for timezone support, so assume UTC */ |
| 255 | + result = dateVal*86400.0; |
| 256 | + } |
242 | 257 |
|
243 | 258 | PG_RETURN_TIMESTAMP(result);
|
244 | 259 | }
|
@@ -324,81 +339,6 @@ abstime_date(PG_FUNCTION_ARGS)
|
324 | 339 | }
|
325 | 340 |
|
326 | 341 |
|
327 |
| -/* date2tm() |
328 |
| - * Convert date to time structure. |
329 |
| - * Note that date is an implicit local time, but the system calls assume |
330 |
| - * that everything is GMT. So, convert to GMT, rotate to local time, |
331 |
| - * and then convert again to try to get the time zones correct. |
332 |
| - */ |
333 |
| -static int |
334 |
| -date2tm(DateADT dateVal, int *tzp, struct tm * tm, double *fsec, char **tzn) |
335 |
| -{ |
336 |
| - struct tm *tx; |
337 |
| - time_t utime; |
338 |
| - |
339 |
| - *fsec = 0; |
340 |
| - |
341 |
| - j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday)); |
342 |
| - tm->tm_hour = 0; |
343 |
| - tm->tm_min = 0; |
344 |
| - tm->tm_sec = 0; |
345 |
| - tm->tm_isdst = -1; |
346 |
| - |
347 |
| - if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday)) |
348 |
| - { |
349 |
| - |
350 |
| - /* convert to system time */ |
351 |
| - utime = ((dateVal + (date2j(2000, 1, 1) - date2j(1970, 1, 1))) * 86400); |
352 |
| - /* rotate to noon to get the right day in time zone */ |
353 |
| - utime += (12 * 60 * 60); |
354 |
| - |
355 |
| -#ifdef USE_POSIX_TIME |
356 |
| - tx = localtime(&utime); |
357 |
| - |
358 |
| - tm->tm_year = tx->tm_year + 1900; |
359 |
| - tm->tm_mon = tx->tm_mon + 1; |
360 |
| - tm->tm_mday = tx->tm_mday; |
361 |
| - tm->tm_isdst = tx->tm_isdst; |
362 |
| - |
363 |
| -#if defined(HAVE_TM_ZONE) |
364 |
| - tm->tm_gmtoff = tx->tm_gmtoff; |
365 |
| - tm->tm_zone = tx->tm_zone; |
366 |
| - |
367 |
| - /* tm_gmtoff is Sun/DEC-ism */ |
368 |
| - *tzp = -(tm->tm_gmtoff); |
369 |
| - if (tzn != NULL) |
370 |
| - *tzn = (char *) tm->tm_zone; |
371 |
| -#elif defined(HAVE_INT_TIMEZONE) |
372 |
| -#ifdef __CYGWIN__ |
373 |
| - *tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone); |
374 |
| -#else |
375 |
| - *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone); |
376 |
| -#endif |
377 |
| - if (tzn != NULL) |
378 |
| - *tzn = tzname[(tm->tm_isdst > 0)]; |
379 |
| -#else |
380 |
| -#error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined |
381 |
| -#endif |
382 |
| -#else /* !USE_POSIX_TIME */ |
383 |
| - *tzp = CTimeZone; /* V7 conventions; don't know timezone? */ |
384 |
| - if (tzn != NULL) |
385 |
| - *tzn = CTZName; |
386 |
| -#endif |
387 |
| - |
388 |
| - /* otherwise, outside of timezone range so convert to GMT... */ |
389 |
| - } |
390 |
| - else |
391 |
| - { |
392 |
| - *tzp = 0; |
393 |
| - tm->tm_isdst = 0; |
394 |
| - if (tzn != NULL) |
395 |
| - *tzn = NULL; |
396 |
| - } |
397 |
| - |
398 |
| - return 0; |
399 |
| -} /* date2tm() */ |
400 |
| - |
401 |
| - |
402 | 342 | /*****************************************************************************
|
403 | 343 | * Time ADT
|
404 | 344 | *****************************************************************************/
|
@@ -906,19 +846,8 @@ datetimetz_timestamp(PG_FUNCTION_ARGS)
|
906 | 846 | DateADT date = PG_GETARG_DATEADT(0);
|
907 | 847 | TimeTzADT *time = PG_GETARG_TIMETZADT_P(1);
|
908 | 848 | Timestamp result;
|
909 |
| - struct tm tt, |
910 |
| - *tm = &tt; |
911 |
| - int tz; |
912 |
| - double fsec = 0; |
913 |
| - char *tzn; |
914 |
| - |
915 |
| - if (date2tm(date, &tz, tm, &fsec, &tzn) != 0) |
916 |
| - elog(ERROR, "Unable to convert date to timestamp"); |
917 |
| - |
918 |
| - if (tm2timestamp(tm, fsec, &time->zone, &result) != 0) |
919 |
| - elog(ERROR, "Timestamp out of range"); |
920 | 849 |
|
921 |
| - result += time->time; |
| 850 | + result = date*86400.0 + time->time + time->zone; |
922 | 851 |
|
923 | 852 | PG_RETURN_TIMESTAMP(result);
|
924 | 853 | }
|
0 commit comments