Allow times of 24:00:00 to match rounding behavior:
authorBruce Momjian
Fri, 14 Oct 2005 11:47:57 +0000 (11:47 +0000)
committerBruce Momjian
Fri, 14 Oct 2005 11:47:57 +0000 (11:47 +0000)
regression=# select '23:59:59.9'::time(0);
   time
----------
 24:00:00
(1 row)

This is bad because:

regression=# select '24:00:00'::time(0);
ERROR:  date/time field value out of range: "24:00:00"

The last example now works.

doc/src/sgml/datatype.sgml
src/backend/utils/adt/datetime.c
src/backend/utils/adt/nabstime.c
src/interfaces/ecpg/pgtypeslib/dt_common.c

index 48caaa2994ffcb26a6e24b340ff6e909f57772c8..0d4819e8094f709ddb77ef46873e114c1d052968 100644 (file)
@@ -1,5 +1,5 @@
 
 
  
@@ -1368,7 +1368,7 @@ SELECT b, char_length(b) FROM test2;
         8 bytes
         times of day only
         00:00:00.00
-        23:59:59.99
+        24:00:00
         1 microsecond / 14 digits
        
        
@@ -1376,7 +1376,7 @@ SELECT b, char_length(b) FROM test2;
         12 bytes
         times of day only, with time zone
         00:00:00.00+12
-        23:59:59.99-12
+        24:00:00-12
         1 microsecond / 14 digits
        
       
index 74dda5441f1684b896e00fad03fd5456551ebce5..faacdb2eba47840db863964d0a502355caf94eb8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.158 2005/10/09 17:21:46 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.159 2005/10/14 11:47:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1114,7 +1114,9 @@ DecodeDateTime(char **field, int *ftype, int nf,
                 * Check upper limit on hours; other limits checked in
                 * DecodeTime()
                 */
-               if (tm->tm_hour > 23)
+               /* test for > 24:00:00 */
+               if  (tm->tm_hour > 24 ||
+                    (tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0)))
                    return DTERR_FIELD_OVERFLOW;
                break;
 
@@ -2243,14 +2245,16 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
    else if (mer == PM && tm->tm_hour != 12)
        tm->tm_hour += 12;
 
+   if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_min > 59 ||
+       tm->tm_sec < 0 || tm->tm_sec > 60 || tm->tm_hour > 24 ||
+       /* test for > 24:00:00 */
+       (tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0 ||
 #ifdef HAVE_INT64_TIMESTAMP
-   if (tm->tm_hour < 0 || tm->tm_hour > 23 || tm->tm_min < 0 ||
-       tm->tm_min > 59 || tm->tm_sec < 0 || tm->tm_sec > 60 ||
+       *fsec > INT64CONST(0))) ||
        *fsec < INT64CONST(0) || *fsec >= USECS_PER_SEC)
        return DTERR_FIELD_OVERFLOW;
 #else
-   if (tm->tm_hour < 0 || tm->tm_hour > 23 || tm->tm_min < 0 ||
-       tm->tm_min > 59 || tm->tm_sec < 0 || tm->tm_sec > 60 ||
+       *fsec > 0)) ||
        *fsec < 0 || *fsec >= 1)
        return DTERR_FIELD_OVERFLOW;
 #endif
index d097b51e8bfecf7d2338a65fb7c02b7314cbc7e4..148ee0abb1c428b940f9ec19341819603918cd17 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.143 2005/09/24 22:54:38 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.144 2005/10/14 11:47:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -184,12 +184,14 @@ tm2abstime(struct pg_tm *tm, int tz)
    AbsoluteTime sec;
 
    /* validate, before going out of range on some members */
-   if (tm->tm_year < 1901 || tm->tm_year > 2038
-       || tm->tm_mon < 1 || tm->tm_mon > 12
-       || tm->tm_mday < 1 || tm->tm_mday > 31
-       || tm->tm_hour < 0 || tm->tm_hour > 23
-       || tm->tm_min < 0 || tm->tm_min > 59
-       || tm->tm_sec < 0 || tm->tm_sec > 60)
+   if (tm->tm_year < 1901 || tm->tm_year > 2038 ||
+       tm->tm_mon < 1 || tm->tm_mon > 12 ||
+       tm->tm_mday < 1 || tm->tm_mday > 31 ||
+       tm->tm_hour < 0 ||
+       tm->tm_hour > 24 || /* test for > 24:00:00 */
+       (tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0)) ||
+       tm->tm_min < 0 || tm->tm_min > 59 ||
+       tm->tm_sec < 0 || tm->tm_sec > 60)
        return INVALID_ABSTIME;
 
    day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE;
index 305f192a7bdc6094f6acb1699b57903b70533e77..b5939c243ec66fe9547ae1b1648985ff8dbf407c 100644 (file)
@@ -2095,7 +2095,9 @@ DecodeDateTime(char **field, int *ftype, int nf,
                 * Check upper limit on hours; other limits checked in
                 * DecodeTime()
                 */
-               if (tm->tm_hour > 23)
+               /* test for > 24:00:00 */
+               if  (tm->tm_hour > 24 ||
+                    (tm->tm_hour == 24 && (tm->tm_min > 0 || tm->tm_sec > 0)))
                    return -1;
                break;
 
@@ -3161,7 +3163,8 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp *d,
            err = 1;
            *minute = 0;
        }
-       if (*hour > 23)
+       if (*hour > 24 ||   /* test for > 24:00:00 */
+           (*hour == 24 && (*minute > 0 || *second > 0)))
        {
            err = 1;
            *hour = 0;