]> granicus.if.org Git - postgresql/commitdiff
Allow times of 24:00:00 to match rounding behavior:
authorBruce Momjian <bruce@momjian.us>
Fri, 14 Oct 2005 11:47:57 +0000 (11:47 +0000)
committerBruce Momjian <bruce@momjian.us>
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 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.160 2005/10/02 23:50:06 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.161 2005/10/14 11:47:56 momjian Exp $
 -->
 
  <chapter id="datatype">
@@ -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 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;