Allow times of 24:00:00 to match rounding behavior:
authorBruce Momjian <[email protected]>
Fri, 14 Oct 2005 11:47:57 +0000 (11:47 +0000)
committerBruce Momjian <[email protected]>
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 31f9ad705976dc13643883f7fb4c6ab5d80e3ae3..44b7160a29e3f47a8c1c083c73be4c7eca404633 100644 (file)
@@ -1368,7 +1368,7 @@ SELECT b, char_length(b) FROM test2;
         <entry>8 bytes</entry>
         <entry>times of day only</entry>
         <entry>00:00:00.00</entry>
-        <entry>23:59:59.99</entry>
+        <entry>24:00:00</entry>
         <entry>1 microsecond / 14 digits</entry>
        </row>
        <row>
@@ -1376,7 +1376,7 @@ SELECT b, char_length(b) FROM test2;
         <entry>12 bytes</entry>
         <entry>times of day only, with time zone</entry>
         <entry>00:00:00.00+12</entry>
-        <entry>23:59:59.99-12</entry>
+        <entry>24:00:00-12</entry>
         <entry>1 microsecond / 14 digits</entry>
        </row>
       </tbody>
index d48cab62819a3720b812442b76db1418c566da9f..3a5461e6f9d1fe42d057553d7d71b7b5f8d9ac1b 100644 (file)
@@ -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 7050083a5274fc899a5d0af2d4c12f2d2049b701..1d2e12cad30cd359c47567e169c11d195dfecefb 100644 (file)
@@ -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;