*gmt -= (tz * INT64CONST(1000000));
#else
*gmt -= tz;
- *gmt = JROUND(*gmt);
#endif
-
}
return gmt;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.120 2005/09/09 02:31:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.121 2005/10/09 17:21:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#else
double trem;
+recalc:
trem = time;
TMODULO(trem, tm->tm_hour, (double)SECS_PER_HOUR);
TMODULO(trem, tm->tm_min, (double)SECS_PER_MINUTE);
TMODULO(trem, tm->tm_sec, 1.0);
+ trem = TIMEROUND(trem);
+ /* roundoff may need to propagate to higher-order fields */
+ if (trem >= 1.0)
+ {
+ time = ceil(time);
+ goto recalc;
+ }
*fsec = trem;
#endif
#else
double trem = time->time;
+recalc:
TMODULO(trem, tm->tm_hour, (double)SECS_PER_HOUR);
TMODULO(trem, tm->tm_min, (double)SECS_PER_MINUTE);
TMODULO(trem, tm->tm_sec, 1.0);
+ trem = TIMEROUND(trem);
+ /* roundoff may need to propagate to higher-order fields */
+ if (trem >= 1.0)
+ {
+ trem = ceil(time->time);
+ goto recalc;
+ }
*fsec = trem;
#endif
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.157 2005/07/23 14:25:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.158 2005/10/09 17:21:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
sprintf(str, "%02d:%02d", tm->tm_hour, tm->tm_min);
/*
- * Print fractional seconds if any. The field widths here should be
- * at least equal to the larger of MAX_TIME_PRECISION and
+ * Print fractional seconds if any. The fractional field widths
+ * here should be equal to the larger of MAX_TIME_PRECISION and
* MAX_TIMESTAMP_PRECISION.
*/
if (fsec != 0)
#ifdef HAVE_INT64_TIMESTAMP
sprintf(str + strlen(str), ":%02d.%06d", tm->tm_sec, fsec);
#else
- sprintf(str + strlen(str), ":%012.9f", tm->tm_sec + fsec);
+ sprintf(str + strlen(str), ":%013.10f", tm->tm_sec + fsec);
#endif
TrimTrailingZeros(str);
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.153 2005/09/09 06:46:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.154 2005/10/09 17:21:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*min = time / SECS_PER_MINUTE;
time -= (*min) * SECS_PER_MINUTE;
*sec = time;
- *fsec = JROUND(time - *sec);
+ *fsec = time - *sec;
#endif
-
- return;
} /* dt2time() */
#endif
}
- time = dt;
#ifdef HAVE_INT64_TIMESTAMP
+ time = dt;
TMODULO(time, date, USECS_PER_DAY);
if (time < INT64CONST(0))
time += USECS_PER_DAY;
date -= 1;
}
+
+ /* add offset to go from J2000 back to standard Julian date */
+ date += POSTGRES_EPOCH_JDATE;
+
+ /* Julian day routine does not work for negative Julian days */
+ if (date < 0 || date > (Timestamp) INT_MAX)
+ return -1;
+
+ j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+ dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
#else
+ time = dt;
TMODULO(time, date, (double)SECS_PER_DAY);
if (time < 0)
{
time += SECS_PER_DAY;
- date -=1;
+ date -= 1;
}
-#endif
/* add offset to go from J2000 back to standard Julian date */
date += POSTGRES_EPOCH_JDATE;
+recalc_d:
/* Julian day routine does not work for negative Julian days */
- if (date <0 || date >(Timestamp) INT_MAX)
+ if (date < 0 || date > (Timestamp) INT_MAX)
return -1;
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+recalc_t:
dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
+ *fsec = TSROUND(*fsec);
+ /* roundoff may need to propagate to higher-order fields */
+ if (*fsec >= 1.0)
+ {
+ time = ceil(time);
+ if (time >= (double)SECS_PER_DAY)
+ {
+ time = 0;
+ date += 1;
+ goto recalc_d;
+ }
+ goto recalc_t;
+ }
+#endif
+
/* Done if no TZ conversion wanted */
if (tzp == NULL)
{
tm->tm_sec = time / USECS_PER_SEC;
*fsec = time - (tm->tm_sec * USECS_PER_SEC);
#else
+recalc:
TMODULO(time, tm->tm_hour, (double)SECS_PER_HOUR);
TMODULO(time, tm->tm_min, (double)SECS_PER_MINUTE);
TMODULO(time, tm->tm_sec, 1.0);
+ time = TSROUND(time);
+ /* roundoff may need to propagate to higher-order fields */
+ if (time >= 1.0)
+ {
+ time = ceil(span.time);
+ goto recalc;
+ }
*fsec = time;
#endif
#else
span->time = (((tm->tm_hour * (double)MINS_PER_HOUR) +
tm->tm_min) * (double)SECS_PER_MINUTE) +
- tm->tm_sec;
- span->time = JROUND(span->time + fsec);
+ tm->tm_sec + fsec;
#endif
return 0;
dt -= (tz * USECS_PER_SEC);
#else
dt -= tz;
- dt = JROUND(dt);
#endif
return dt;
} /* dt2local() */
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
errmsg("cannot subtract infinite timestamps")));
-#ifdef HAVE_INT64_TIMESTAMP
result->time = dt1 - dt2;
-#else
- result->time = JROUND(dt1 - dt2);
-#endif
result->month = 0;
result->day = 0;
result->month = span1->month + span2->month;
result->day = span1->day + span2->day;
-#ifdef HAVE_INT64_TIMESTAMP
result->time = span1->time + span2->time;
-#else
- result->time = JROUND(span1->time + span2->time);
-#endif
PG_RETURN_INTERVAL_P(result);
}
result->month = span1->month - span2->month;
result->day = span1->day - span2->day;
-#ifdef HAVE_INT64_TIMESTAMP
result->time = span1->time - span2->time;
-#else
- result->time = JROUND(span1->time - span2->time);
-#endif
PG_RETURN_INTERVAL_P(result);
}
#ifdef HAVE_INT64_TIMESTAMP
result->time = rint(span->time * factor + day_remainder * USECS_PER_DAY);
#else
- result->time = JROUND(span->time * factor + day_remainder * SECS_PER_DAY);
+ result->time = span->time * factor + day_remainder * SECS_PER_DAY;
#endif
result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours,
result->time += rint(day_remainder * USECS_PER_DAY);
#else
result->time += day_remainder * SECS_PER_DAY;
- result->time = JROUND(result->time);
#endif
result = DatumGetIntervalP(DirectFunctionCall1(interval_justify_hours,
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/date.h,v 1.30 2005/02/25 16:13:29 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/utils/date.h,v 1.31 2005/10/09 17:21:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#define MAX_TIME_PRECISION 10
+/* round off to MAX_TIME_PRECISION decimal places */
+#define TIME_PREC_INV 10000000000.0
+#define TIMEROUND(j) (rint(((double) (j)) * TIME_PREC_INV) / TIME_PREC_INV)
+
#define DatumGetDateADT(X) ((DateADT) DatumGetInt32(X))
#define DatumGetTimeADT(X) ((TimeADT) DatumGetFloat8(X))
#define DatumGetTimeTzADTP(X) ((TimeTzADT *) DatumGetPointer(X))
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.55 2005/10/07 20:13:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/timestamp.h,v 1.56 2005/10/09 17:21:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
typedef double fsec_t;
-#define TIME_PREC_INV 1000000.0
-#define JROUND(j) (rint(((double) (j)) * TIME_PREC_INV) / TIME_PREC_INV)
+/* round off to MAX_TIMESTAMP_PRECISION decimal places */
+/* note: this is also used for rounding off intervals */
+#define TS_PREC_INV 1000000.0
+#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
+
#endif
#define TIMESTAMP_MASK(b) (1 << (b))
typedef double fsec_t;
-#define TIME_PREC_INV 1000000.0
-#define JROUND(j) (rint(((double) (j)) * TIME_PREC_INV) / TIME_PREC_INV)
+/* round off to MAX_TIMESTAMP_PRECISION decimal places */
+/* note: this is also used for rounding off intervals */
+#define TS_PREC_INV 1000000.0
+#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV)
+
#endif
#define USE_POSTGRES_DATES 0
*min = time / SECS_PER_MINUTE;
time -= (*min) * SECS_PER_MINUTE;
*sec = time;
- *fsec = JROUND(time - *sec);
+ *fsec = time - *sec;
#endif
- return;
} /* dt2time() */
tm->tm_sec = time / USECS_PER_SEC;
*fsec = time - (tm->tm_sec * USECS_PER_SEC);
#else
+recalc:
TMODULO(time, tm->tm_mday, (double)SECS_PER_DAY);
TMODULO(time, tm->tm_hour, (double)SECS_PER_HOUR);
TMODULO(time, tm->tm_min, (double)SECS_PER_MINUTE);
TMODULO(time, tm->tm_sec, 1.0);
+ time = TSROUND(time);
+ /* roundoff may need to propagate to higher-order fields */
+ if (time >= 1.0)
+ {
+ time = ceil(span.time);
+ goto recalc;
+ }
*fsec = time;
#endif
span->time = (((((tm->tm_mday * (double)HOURS_PER_DAY) +
tm->tm_hour) * (double)MINS_PER_HOUR) +
tm->tm_min) * (double)SECS_PER_MINUTE) +
- tm->tm_sec;
- span->time = JROUND(span->time + fsec);
+ tm->tm_sec + fsec;
#endif
return 0;
dt -= (tz * USECS_PER_SEC);
#else
dt -= tz;
- dt = JROUND(dt);
#endif
return dt;
} /* dt2local() */
*min = time / SECS_PER_MINUTE;
time -= (*min) * SECS_PER_MINUTE;
*sec = time;
- *fsec = JROUND(time - *sec);
+ *fsec = time - *sec;
#endif
- return;
} /* dt2time() */
/* timestamp2tm()
timestamp2tm(timestamp dt, int *tzp, struct tm *tm, fsec_t *fsec, char **tzn)
{
#ifdef HAVE_INT64_TIMESTAMP
- int dDate,
+ int64 dDate,
date0;
int64 time;
#else
date0 = date2j(2000, 1, 1);
- time = dt;
#ifdef HAVE_INT64_TIMESTAMP
+ time = dt;
TMODULO(time, dDate, USECS_PER_DAY);
if (time < INT64CONST(0))
time += USECS_PER_DAY;
dDate -= 1;
}
+
+ /* add offset to go from J2000 back to standard Julian date */
+ dDate += date0;
+
+ /* Julian day routine does not work for negative Julian days */
+ if (dDate < 0 || dDate > (timestamp) INT_MAX)
+ return -1;
+
+ j2date((int) dDate, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+ dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
#else
+ time = dt;
TMODULO(time, dDate, (double)SECS_PER_DAY);
if (time < 0)
time += SECS_PER_DAY;
dDate -= 1;
}
-#endif
-
- /* Julian day routine does not work for negative Julian days */
- if (dDate < -date0)
- return -1;
/* add offset to go from J2000 back to standard Julian date */
dDate += date0;
+recalc_d:
+ /* Julian day routine does not work for negative Julian days */
+ if (dDate < 0 || dDate > (timestamp) INT_MAX)
+ return -1;
+
j2date((int) dDate, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
+recalc_t:
dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
+ *fsec = TSROUND(*fsec);
+ /* roundoff may need to propagate to higher-order fields */
+ if (*fsec >= 1.0)
+ {
+ time = ceil(time);
+ if (time >= (double)SECS_PER_DAY)
+ {
+ time = 0;
+ dDate += 1;
+ goto recalc_d;
+ }
+ goto recalc_t;
+ }
+#endif
+
if (tzp != NULL)
{
/*
if (TIMESTAMP_NOT_FINITE(*ts1) || TIMESTAMP_NOT_FINITE(*ts2))
return PGTYPES_TS_ERR_EINFTIME;
else
-#ifdef HAVE_INT64_TIMESTAMP
iv->time = (ts1 - ts2);
-#else
- iv->time = JROUND(ts1 - ts2);
-#endif
iv->month = 0;