datetime.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:13k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * datetime.c
  4.  *   implements DATE and TIME data types specified in SQL-92 standard
  5.  *
  6.  * Copyright (c) 1994-5, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.33.2.1 1999/08/02 05:24:51 scrappy Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. #include <limits.h>
  15. #include "postgres.h"
  16. #ifdef HAVE_FLOAT_H
  17. #include <float.h>
  18. #endif
  19. #include "miscadmin.h"
  20. #include "utils/builtins.h"
  21. static int date2tm(DateADT dateVal, int *tzp, struct tm * tm, double *fsec, char **tzn);
  22. /*****************************************************************************
  23.  *  Date ADT
  24.  *****************************************************************************/
  25. /* date_in()
  26.  * Given date text string, convert to internal date format.
  27.  */
  28. DateADT
  29. date_in(char *str)
  30. {
  31. DateADT date;
  32. double fsec;
  33. struct tm tt,
  34.    *tm = &tt;
  35. int tzp;
  36. int dtype;
  37. int nf;
  38. char    *field[MAXDATEFIELDS];
  39. int ftype[MAXDATEFIELDS];
  40. char lowstr[MAXDATELEN + 1];
  41. if (!PointerIsValid(str))
  42. elog(ERROR, "Bad (null) date external representation", NULL);
  43. #ifdef DATEDEBUG
  44. printf("date_in- input string is %sn", str);
  45. #endif
  46. if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
  47.  || (DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0))
  48. elog(ERROR, "Bad date external representation '%s'", str);
  49. switch (dtype)
  50. {
  51. case DTK_DATE:
  52. break;
  53. case DTK_CURRENT:
  54. GetCurrentTime(tm);
  55. break;
  56. case DTK_EPOCH:
  57. tm->tm_year = 1970;
  58. tm->tm_mon = 1;
  59. tm->tm_mday = 1;
  60. break;
  61. default:
  62. elog(ERROR, "Unrecognized date external representation '%s'", str);
  63. }
  64. date = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
  65. return date;
  66. } /* date_in() */
  67. /* date_out()
  68.  * Given internal format date, convert to text string.
  69.  */
  70. char *
  71. date_out(DateADT date)
  72. {
  73. char    *result;
  74. struct tm tt,
  75.    *tm = &tt;
  76. char buf[MAXDATELEN + 1];
  77. j2date((date + date2j(2000, 1, 1)),
  78.    &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
  79. EncodeDateOnly(tm, DateStyle, buf);
  80. result = palloc(strlen(buf) + 1);
  81. strcpy(result, buf);
  82. return result;
  83. } /* date_out() */
  84. bool
  85. date_eq(DateADT dateVal1, DateADT dateVal2)
  86. {
  87. return dateVal1 == dateVal2;
  88. }
  89. bool
  90. date_ne(DateADT dateVal1, DateADT dateVal2)
  91. {
  92. return dateVal1 != dateVal2;
  93. }
  94. bool
  95. date_lt(DateADT dateVal1, DateADT dateVal2)
  96. {
  97. return dateVal1 < dateVal2;
  98. } /* date_lt() */
  99. bool
  100. date_le(DateADT dateVal1, DateADT dateVal2)
  101. {
  102. return dateVal1 <= dateVal2;
  103. } /* date_le() */
  104. bool
  105. date_gt(DateADT dateVal1, DateADT dateVal2)
  106. {
  107. return dateVal1 > dateVal2;
  108. } /* date_gt() */
  109. bool
  110. date_ge(DateADT dateVal1, DateADT dateVal2)
  111. {
  112. return dateVal1 >= dateVal2;
  113. } /* date_ge() */
  114. int
  115. date_cmp(DateADT dateVal1, DateADT dateVal2)
  116. {
  117. if (dateVal1 < dateVal2)
  118. return -1;
  119. else if (dateVal1 > dateVal2)
  120. return 1;
  121. return 0;
  122. } /* date_cmp() */
  123. DateADT
  124. date_larger(DateADT dateVal1, DateADT dateVal2)
  125. {
  126. return date_gt(dateVal1, dateVal2) ? dateVal1 : dateVal2;
  127. } /* date_larger() */
  128. DateADT
  129. date_smaller(DateADT dateVal1, DateADT dateVal2)
  130. {
  131. return date_lt(dateVal1, dateVal2) ? dateVal1 : dateVal2;
  132. } /* date_smaller() */
  133. /* Compute difference between two dates in days.
  134.  */
  135. int4
  136. date_mi(DateADT dateVal1, DateADT dateVal2)
  137. {
  138. return dateVal1 - dateVal2;
  139. } /* date_mi() */
  140. /* Add a number of days to a date, giving a new date.
  141.  * Must handle both positive and negative numbers of days.
  142.  */
  143. DateADT
  144. date_pli(DateADT dateVal, int4 days)
  145. {
  146. return dateVal + days;
  147. } /* date_pli() */
  148. /* Subtract a number of days from a date, giving a new date.
  149.  */
  150. DateADT
  151. date_mii(DateADT dateVal, int4 days)
  152. {
  153. return date_pli(dateVal, -days);
  154. } /* date_mii() */
  155. /* date_datetime()
  156.  * Convert date to datetime data type.
  157.  */
  158. DateTime   *
  159. date_datetime(DateADT dateVal)
  160. {
  161. DateTime   *result;
  162. struct tm tt,
  163.    *tm = &tt;
  164. int tz;
  165. double fsec = 0;
  166. char    *tzn;
  167. result = palloc(sizeof(DateTime));
  168. if (date2tm(dateVal, &tz, tm, &fsec, &tzn) != 0)
  169. elog(ERROR, "Unable to convert date to datetime", NULL);
  170. #ifdef DATEDEBUG
  171. printf("date_datetime- date is %d.%02d.%02dn", tm->tm_year, tm->tm_mon, tm->tm_mday);
  172. printf("date_datetime- time is %02d:%02d:%02d %.7fn", tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
  173. #endif
  174. if (tm2datetime(tm, fsec, &tz, result) != 0)
  175. elog(ERROR, "Datetime out of range", NULL);
  176. return result;
  177. } /* date_datetime() */
  178. /* datetime_date()
  179.  * Convert datetime to date data type.
  180.  */
  181. DateADT
  182. datetime_date(DateTime *datetime)
  183. {
  184. DateADT result;
  185. struct tm tt,
  186.    *tm = &tt;
  187. int tz;
  188. double fsec;
  189. char    *tzn;
  190. if (!PointerIsValid(datetime))
  191. elog(ERROR, "Unable to convert null datetime to date", NULL);
  192. if (DATETIME_NOT_FINITE(*datetime))
  193. elog(ERROR, "Unable to convert datetime to date", NULL);
  194. if (DATETIME_IS_EPOCH(*datetime))
  195. {
  196. datetime2tm(SetDateTime(*datetime), NULL, tm, &fsec, NULL);
  197. }
  198. else if (DATETIME_IS_CURRENT(*datetime))
  199. {
  200. datetime2tm(SetDateTime(*datetime), &tz, tm, &fsec, &tzn);
  201. }
  202. else
  203. {
  204. if (datetime2tm(*datetime, &tz, tm, &fsec, &tzn) != 0)
  205. elog(ERROR, "Unable to convert datetime to date", NULL);
  206. }
  207. result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1));
  208. return result;
  209. } /* datetime_date() */
  210. /* abstime_date()
  211.  * Convert abstime to date data type.
  212.  */
  213. DateADT
  214. abstime_date(AbsoluteTime abstime)
  215. {
  216. DateADT result;
  217. struct tm tt,
  218.    *tm = &tt;
  219. int tz;
  220. switch (abstime)
  221. {
  222. case INVALID_ABSTIME:
  223. case NOSTART_ABSTIME:
  224. case NOEND_ABSTIME:
  225. elog(ERROR, "Unable to convert reserved abstime value to date", NULL);
  226. /*
  227.  * pretend to drop through to make compiler think that result
  228.  * will be set
  229.  */
  230. case EPOCH_ABSTIME:
  231. result = date2j(1970, 1, 1) - date2j(2000, 1, 1);
  232. break;
  233. case CURRENT_ABSTIME:
  234. GetCurrentTime(tm);
  235. result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
  236. break;
  237. default:
  238. abstime2tm(abstime, &tz, tm, NULL);
  239. result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - date2j(2000, 1, 1);
  240. break;
  241. }
  242. return result;
  243. } /* abstime_date() */
  244. /* date2tm()
  245.  * Convert date to time structure.
  246.  * Note that date is an implicit local time, but the system calls assume
  247.  * that everything is GMT. So, convert to GMT, rotate to local time,
  248.  * and then convert again to try to get the time zones correct.
  249.  */
  250. static int
  251. date2tm(DateADT dateVal, int *tzp, struct tm * tm, double *fsec, char **tzn)
  252. {
  253. struct tm  *tx;
  254. time_t utime;
  255. *fsec = 0;
  256. j2date((dateVal + date2j(2000, 1, 1)), &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
  257. tm->tm_hour = 0;
  258. tm->tm_min = 0;
  259. tm->tm_sec = 0;
  260. tm->tm_isdst = -1;
  261. if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
  262. {
  263. /* convert to system time */
  264. utime = ((dateVal + (date2j(2000, 1, 1) - date2j(1970, 1, 1))) * 86400);
  265. /* rotate to noon to get the right day in time zone */
  266. utime += (12 * 60 * 60);
  267. #ifdef USE_POSIX_TIME
  268. tx = localtime(&utime);
  269. #ifdef DATEDEBUG
  270. #if defined(HAVE_TM_ZONE)
  271. printf("date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s dst=%dn",
  272.    tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
  273.    tx->tm_zone, tx->tm_isdst);
  274. #elif defined(HAVE_INT_TIMEZONE)
  275. printf("date2tm- (localtime) %d.%02d.%02d %02d:%02d:%02.0f %s %s dst=%dn",
  276.    tx->tm_year, tx->tm_mon, tx->tm_mday, tx->tm_hour, tx->tm_min, (double) tm->tm_sec,
  277.    tzname[0], tzname[1], tx->tm_isdst);
  278. #endif
  279. #endif
  280. tm->tm_year = tx->tm_year + 1900;
  281. tm->tm_mon = tx->tm_mon + 1;
  282. tm->tm_mday = tx->tm_mday;
  283. tm->tm_isdst = tx->tm_isdst;
  284. #if defined(HAVE_TM_ZONE)
  285. tm->tm_gmtoff = tx->tm_gmtoff;
  286. tm->tm_zone = tx->tm_zone;
  287. /* tm_gmtoff is Sun/DEC-ism */
  288. *tzp = -(tm->tm_gmtoff);
  289. if (tzn != NULL)
  290. *tzn = (char *) tm->tm_zone;
  291. #elif defined(HAVE_INT_TIMEZONE)
  292. #ifdef __CYGWIN__
  293. *tzp = (tm->tm_isdst ? (_timezone - 3600) : _timezone);
  294. #else
  295. *tzp = (tm->tm_isdst ? (timezone - 3600) : timezone);
  296. #endif
  297. if (tzn != NULL)
  298. *tzn = tzname[(tm->tm_isdst > 0)];
  299. #else
  300. #error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
  301. #endif
  302. #else /* !USE_POSIX_TIME */
  303. *tzp = CTimeZone; /* V7 conventions; don't know timezone? */
  304. if (tzn != NULL)
  305. *tzn = CTZName;
  306. #endif
  307. /* otherwise, outside of timezone range so convert to GMT... */
  308. }
  309. else
  310. {
  311. #ifdef DATEDEBUG
  312. printf("date2tm- convert %d-%d-%d %d:%d%d to datetimen",
  313.    tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
  314. #endif
  315. *tzp = 0;
  316. tm->tm_isdst = 0;
  317. if (tzn != NULL)
  318. *tzn = NULL;
  319. }
  320. #ifdef DATEDEBUG
  321. #if defined(HAVE_TM_ZONE)
  322. printf("date2tm- %d.%02d.%02d %02d:%02d:%02.0f (%d %s) dst=%dn",
  323.    tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, (double) tm->tm_sec,
  324.    *tzp, tm->tm_zone, tm->tm_isdst);
  325. #elif defined(HAVE_INT_TIMEZONE)
  326. printf("date2tm- %d.%02d.%02d %02d:%02d:%02.0f (%d %s %s) dst=%dn",
  327.    tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, (double) tm->tm_sec,
  328.    *tzp, tzname[0], tzname[1], tm->tm_isdst);
  329. #endif
  330. #endif
  331. return 0;
  332. } /* date2tm() */
  333. /*****************************************************************************
  334.  *  Time ADT
  335.  *****************************************************************************/
  336. TimeADT    *
  337. time_in(char *str)
  338. {
  339. TimeADT    *time;
  340. double fsec;
  341. struct tm tt,
  342.    *tm = &tt;
  343. int nf;
  344. char lowstr[MAXDATELEN + 1];
  345. char    *field[MAXDATEFIELDS];
  346. int dtype;
  347. int ftype[MAXDATEFIELDS];
  348. if (!PointerIsValid(str))
  349. elog(ERROR, "Bad (null) time external representation", NULL);
  350. if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
  351. || (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec) != 0))
  352. elog(ERROR, "Bad time external representation '%s'", str);
  353. time = palloc(sizeof(TimeADT));
  354. *time = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
  355. return time;
  356. } /* time_in() */
  357. char *
  358. time_out(TimeADT *time)
  359. {
  360. char    *result;
  361. struct tm tt,
  362.    *tm = &tt;
  363. double fsec;
  364. char buf[MAXDATELEN + 1];
  365. if (!PointerIsValid(time))
  366. return NULL;
  367. tm->tm_hour = (*time / (60 * 60));
  368. tm->tm_min = (((int) (*time / 60)) % 60);
  369. tm->tm_sec = (((int) *time) % 60);
  370. fsec = 0;
  371. EncodeTimeOnly(tm, fsec, DateStyle, buf);
  372. result = palloc(strlen(buf) + 1);
  373. strcpy(result, buf);
  374. return result;
  375. } /* time_out() */
  376. bool
  377. time_eq(TimeADT *time1, TimeADT *time2)
  378. {
  379. if (!PointerIsValid(time1) || !PointerIsValid(time2))
  380. return FALSE;
  381. return *time1 == *time2;
  382. } /* time_eq() */
  383. bool
  384. time_ne(TimeADT *time1, TimeADT *time2)
  385. {
  386. if (!PointerIsValid(time1) || !PointerIsValid(time2))
  387. return FALSE;
  388. return *time1 != *time2;
  389. } /* time_eq() */
  390. bool
  391. time_lt(TimeADT *time1, TimeADT *time2)
  392. {
  393. if (!PointerIsValid(time1) || !PointerIsValid(time2))
  394. return FALSE;
  395. return *time1 < *time2;
  396. } /* time_eq() */
  397. bool
  398. time_le(TimeADT *time1, TimeADT *time2)
  399. {
  400. if (!PointerIsValid(time1) || !PointerIsValid(time2))
  401. return FALSE;
  402. return *time1 <= *time2;
  403. } /* time_eq() */
  404. bool
  405. time_gt(TimeADT *time1, TimeADT *time2)
  406. {
  407. if (!PointerIsValid(time1) || !PointerIsValid(time2))
  408. return FALSE;
  409. return *time1 > *time2;
  410. } /* time_eq() */
  411. bool
  412. time_ge(TimeADT *time1, TimeADT *time2)
  413. {
  414. if (!PointerIsValid(time1) || !PointerIsValid(time2))
  415. return FALSE;
  416. return *time1 >= *time2;
  417. } /* time_eq() */
  418. int
  419. time_cmp(TimeADT *time1, TimeADT *time2)
  420. {
  421. return (*time1 < *time2) ? -1 : (((*time1 > *time2) ? 1 : 0));
  422. } /* time_cmp() */
  423. /* datetime_time()
  424.  * Convert datetime to time data type.
  425.  */
  426. TimeADT    *
  427. datetime_time(DateTime *datetime)
  428. {
  429. TimeADT    *result;
  430. struct tm tt,
  431.    *tm = &tt;
  432. int tz;
  433. double fsec;
  434. char    *tzn;
  435. if (!PointerIsValid(datetime))
  436. elog(ERROR, "Unable to convert null datetime to date", NULL);
  437. if (DATETIME_NOT_FINITE(*datetime))
  438. elog(ERROR, "Unable to convert datetime to date", NULL);
  439. if (DATETIME_IS_EPOCH(*datetime))
  440. {
  441. datetime2tm(SetDateTime(*datetime), NULL, tm, &fsec, NULL);
  442. }
  443. else if (DATETIME_IS_CURRENT(*datetime))
  444. {
  445. datetime2tm(SetDateTime(*datetime), &tz, tm, &fsec, &tzn);
  446. }
  447. else
  448. {
  449. if (datetime2tm(*datetime, &tz, tm, &fsec, &tzn) != 0)
  450. elog(ERROR, "Unable to convert datetime to date", NULL);
  451. }
  452. result = palloc(sizeof(TimeADT));
  453. *result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec + fsec);
  454. return result;
  455. } /* datetime_time() */
  456. /* datetime_datetime()
  457.  * Convert date and time to datetime data type.
  458.  */
  459. DateTime   *
  460. datetime_datetime(DateADT date, TimeADT *time)
  461. {
  462. DateTime   *result;
  463. if (!PointerIsValid(time))
  464. {
  465. result = palloc(sizeof(DateTime));
  466. DATETIME_INVALID(*result);
  467. }
  468. else
  469. {
  470. result = date_datetime(date);
  471. *result += *time;
  472. }
  473. return result;
  474. } /* datetime_datetime() */
  475. int32 /* RelativeTime */
  476. int4reltime(int32 timevalue)
  477. {
  478. return timevalue;
  479. }