summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/date.c17
-rw-r--r--src/backend/utils/adt/datetime.c98
-rw-r--r--src/include/utils/date.h4
3 files changed, 48 insertions, 71 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 7f15784320c..f9d976ad65d 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.73.2.2 2003/01/09 01:07:17 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.73.2.3 2003/01/29 01:09:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -619,7 +619,7 @@ static void
AdjustTimeForTypmod(TimeADT *time, int32 typmod)
{
#ifdef HAVE_INT64_TIMESTAMP
- static const int64 TimeScales[MAX_TIMESTAMP_PRECISION + 1] = {
+ static const int64 TimeScales[MAX_TIME_PRECISION + 1] = {
INT64CONST(1000000),
INT64CONST(100000),
INT64CONST(10000),
@@ -629,7 +629,7 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
INT64CONST(1)
};
- static const int64 TimeOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
+ static const int64 TimeOffsets[MAX_TIME_PRECISION + 1] = {
INT64CONST(500000),
INT64CONST(50000),
INT64CONST(5000),
@@ -640,14 +640,19 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
};
#else
- static const double TimeScales[MAX_TIMESTAMP_PRECISION + 1] = {
+ /* note MAX_TIME_PRECISION differs in this case */
+ static const double TimeScales[MAX_TIME_PRECISION + 1] = {
1,
10,
100,
1000,
10000,
100000,
- 1000000
+ 1000000,
+ 10000000,
+ 100000000,
+ 1000000000,
+ 10000000000
};
#endif
@@ -656,7 +661,7 @@ AdjustTimeForTypmod(TimeADT *time, int32 typmod)
/*
* Note: this round-to-nearest code is not completely consistent
* about rounding values that are exactly halfway between integral
- * values. On most platforms, rint() will implement round-to-nearest,
+ * values. On most platforms, rint() will implement round-to-nearest-even,
* but the integer code always rounds up (away from zero). Is it
* worth trying to be consistent?
*/
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 38655ceb5b1..b21c5f217d1 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.96.2.2 2003/01/16 00:27:17 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.96.2.3 2003/01/29 01:09:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -667,14 +667,13 @@ TrimTrailingZeros(char *str)
}
#endif
- /* chop off trailing zeros... */
+ /* chop off trailing zeros... but leave at least 2 fractional digits */
while ((*(str + len - 1) == '0')
&& (*(str + len - 3) != '.'))
{
len--;
*(str + len) = '\0';
}
- return;
}
@@ -3145,33 +3144,22 @@ EncodeDateOnly(struct tm * tm, int style, char *str)
int
EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str)
{
-#ifndef HAVE_INT64_TIMESTAMP
- fsec_t sec;
-#endif
-
if ((tm->tm_hour < 0) || (tm->tm_hour > 24))
return -1;
-#ifndef HAVE_INT64_TIMESTAMP
- sec = (tm->tm_sec + fsec);
-#endif
-
sprintf(str, "%02d:%02d", tm->tm_hour, tm->tm_min);
/*
- * If we have fractional seconds, then include a decimal point We will
- * do up to 6 fractional digits, and we have rounded any inputs to
- * eliminate anything to the right of 6 digits anyway. If there are no
- * fractional seconds, then do not bother printing a decimal point at
- * all. - thomas 2001-09-29
+ * Print fractional seconds if any. The field widths here should be
+ * at least equal to the larger of MAX_TIME_PRECISION and
+ * MAX_TIMESTAMP_PRECISION.
*/
if (fsec != 0)
{
#ifdef HAVE_INT64_TIMESTAMP
- sprintf((str + strlen(str)), ":%02d", tm->tm_sec);
- sprintf((str + strlen(str)), ".%06d", fsec);
+ sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec);
#else
- sprintf((str + strlen(str)), ":%013.10f", sec);
+ sprintf((str + strlen(str)), ":%013.10f", tm->tm_sec + fsec);
#endif
/* chop off trailing pairs of zeros... */
while ((strcmp((str + strlen(str) - 2), "00") == 0)
@@ -3179,11 +3167,7 @@ EncodeTimeOnly(struct tm * tm, fsec_t fsec, int *tzp, int style, char *str)
*(str + strlen(str) - 2) = '\0';
}
else
-#ifdef HAVE_INT64_TIMESTAMP
sprintf((str + strlen(str)), ":%02d", tm->tm_sec);
-#else
- sprintf((str + strlen(str)), ":%02.0f", sec);
-#endif
if (tzp != NULL)
{
@@ -3217,20 +3201,12 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
hour,
min;
-#ifndef HAVE_INT64_TIMESTAMP
- fsec_t sec;
-#endif
-
/*
* Why are we checking only the month field? Change this to an
* assert... if ((tm->tm_mon < 1) || (tm->tm_mon > 12)) return -1;
*/
Assert((tm->tm_mon >= 1) && (tm->tm_mon <= 12));
-#ifndef HAVE_INT64_TIMESTAMP
- sec = (tm->tm_sec + fsec);
-#endif
-
switch (style)
{
case USE_ISO_DATES:
@@ -3241,21 +3217,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
/*
- * If we have fractional seconds, then include a decimal point
- * We will do up to 6 fractional digits, and we have rounded
- * any inputs to eliminate anything to the right of 6 digits
- * anyway. If there are no fractional seconds, then do not
- * bother printing a decimal point at all. - thomas 2001-09-29
+ * Print fractional seconds if any. The field widths here should
+ * be at least equal to MAX_TIMESTAMP_PRECISION.
+ *
+ * In float mode, don't print fractional seconds before 1 AD,
+ * since it's unlikely there's any precision left ...
*/
#ifdef HAVE_INT64_TIMESTAMP
if (fsec != 0)
{
- sprintf((str + strlen(str)), ":%02d", tm->tm_sec);
- sprintf((str + strlen(str)), ".%06d", fsec);
+ sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec);
#else
if ((fsec != 0) && (tm->tm_year > 0))
{
- sprintf((str + strlen(str)), ":%013.10f", sec);
+ sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec);
#endif
TrimTrailingZeros(str);
}
@@ -3292,21 +3267,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
tm->tm_hour, tm->tm_min);
/*
- * If we have fractional seconds, then include a decimal point
- * We will do up to 6 fractional digits, and we have rounded
- * any inputs to eliminate anything to the right of 6 digits
- * anyway. If there are no fractional seconds, then do not
- * bother printing a decimal point at all. - thomas 2001-09-29
+ * Print fractional seconds if any. The field widths here should
+ * be at least equal to MAX_TIMESTAMP_PRECISION.
+ *
+ * In float mode, don't print fractional seconds before 1 AD,
+ * since it's unlikely there's any precision left ...
*/
#ifdef HAVE_INT64_TIMESTAMP
if (fsec != 0)
{
- sprintf((str + strlen(str)), ":%02d", tm->tm_sec);
- sprintf((str + strlen(str)), ".%06d", fsec);
+ sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec);
#else
if ((fsec != 0) && (tm->tm_year > 0))
{
- sprintf((str + strlen(str)), ":%013.10f", sec);
+ sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec);
#endif
TrimTrailingZeros(str);
}
@@ -3339,21 +3313,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
tm->tm_hour, tm->tm_min);
/*
- * If we have fractional seconds, then include a decimal point
- * We will do up to 6 fractional digits, and we have rounded
- * any inputs to eliminate anything to the right of 6 digits
- * anyway. If there are no fractional seconds, then do not
- * bother printing a decimal point at all. - thomas 2001-09-29
+ * Print fractional seconds if any. The field widths here should
+ * be at least equal to MAX_TIMESTAMP_PRECISION.
+ *
+ * In float mode, don't print fractional seconds before 1 AD,
+ * since it's unlikely there's any precision left ...
*/
#ifdef HAVE_INT64_TIMESTAMP
if (fsec != 0)
{
- sprintf((str + strlen(str)), ":%02d", tm->tm_sec);
- sprintf((str + strlen(str)), ".%06d", fsec);
+ sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec);
#else
if ((fsec != 0) && (tm->tm_year > 0))
{
- sprintf((str + strlen(str)), ":%013.10f", sec);
+ sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec);
#endif
TrimTrailingZeros(str);
}
@@ -3394,21 +3367,20 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
sprintf((str + 10), " %02d:%02d", tm->tm_hour, tm->tm_min);
/*
- * If we have fractional seconds, then include a decimal point
- * We will do up to 6 fractional digits, and we have rounded
- * any inputs to eliminate anything to the right of 6 digits
- * anyway. If there are no fractional seconds, then do not
- * bother printing a decimal point at all. - thomas 2001-09-29
+ * Print fractional seconds if any. The field widths here should
+ * be at least equal to MAX_TIMESTAMP_PRECISION.
+ *
+ * In float mode, don't print fractional seconds before 1 AD,
+ * since it's unlikely there's any precision left ...
*/
#ifdef HAVE_INT64_TIMESTAMP
if (fsec != 0)
{
- sprintf((str + strlen(str)), ":%02d", tm->tm_sec);
- sprintf((str + strlen(str)), ".%06d", fsec);
+ sprintf((str + strlen(str)), ":%02d.%06d", tm->tm_sec, fsec);
#else
if ((fsec != 0) && (tm->tm_year > 0))
{
- sprintf((str + strlen(str)), ":%013.10f", sec);
+ sprintf((str + strlen(str)), ":%09.6f", tm->tm_sec + fsec);
#endif
TrimTrailingZeros(str);
}
diff --git a/src/include/utils/date.h b/src/include/utils/date.h
index eaaac77c16a..4b3edd0b98a 100644
--- a/src/include/utils/date.h
+++ b/src/include/utils/date.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: date.h,v 1.21 2002/09/04 20:31:45 momjian Exp $
+ * $Id: date.h,v 1.21.2.1 2003/01/29 01:09:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -41,7 +41,7 @@ typedef struct
#ifdef HAVE_INT64_TIMESTAMP
#define MAX_TIME_PRECISION 6
#else
-#define MAX_TIME_PRECISION 13
+#define MAX_TIME_PRECISION 10
#endif
/*