Thread: Consistent timestamp input

Consistent timestamp input

From
"Greg Sabino Mullane"
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message



This one bugged me so much, I made a patch for it. It enforces
consistent interpretation of date input:

Valid:   YYYY-MM-DD   2003-06-23
Invalid: YYYY-DD-MM   2003-23-06
Valid:   DD-MM-YYYY   23-06-2003
Invalid: MM-DD-YYYY   06-23-2003



Index: datetime.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/datetime.c,v
retrieving revision 1.105
diff -c -r1.105 datetime.c
*** datetime.c    18 May 2003 01:06:26 -0000    1.105
--- datetime.c    23 Jun 2003 20:42:37 -0000
***************
*** 2391,2440 ****

          tm->tm_year = val;
      }
!
!     /* already have year? then could be month */
!     else if ((fmask & DTK_M(YEAR)) && (!(fmask & DTK_M(MONTH)))
!              && ((val >= 1) && (val <= 12)))
      {
!         *tmask = DTK_M(MONTH);
!         tm->tm_mon = val;
      }
!     /* no year and EuroDates enabled? then could be day */
!     else if ((EuroDates || (fmask & DTK_M(MONTH)))
!              && (!(fmask & DTK_M(YEAR)) && !(fmask & DTK_M(DAY)))
!              && ((val >= 1) && (val <= 31)))
!     {
!         *tmask = DTK_M(DAY);
!         tm->tm_mday = val;
!     }
!     else if ((!(fmask & DTK_M(MONTH)))
!              && ((val >= 1) && (val <= 12)))
!     {
!         *tmask = DTK_M(MONTH);
!         tm->tm_mon = val;
!     }
!     else if ((!(fmask & DTK_M(DAY)))
!              && ((val >= 1) && (val <= 31)))
!     {
!         *tmask = DTK_M(DAY);
!         tm->tm_mday = val;
!     }
!
!     /*
!      * Check for 2 or 4 or more digits, but currently we reach here only
!      * if two digits. - thomas 2000-03-28
!      */
!     else if (!(fmask & DTK_M(YEAR))
!              && ((flen >= 4) || (flen == 2)))
      {
!         *tmask = DTK_M(YEAR);
!         tm->tm_year = val;
!
!         /* adjust ONLY if exactly two digits... */
!         *is2digits = (flen == 2);
      }
-     else
-         return -1;

      return 0;
  }    /* DecodeNumber() */
--- 2391,2442 ----

          tm->tm_year = val;
      }
!     /* For ease of reading, break this into "year" and "not-year" */
!     else if ((fmask & DTK_M(YEAR)))
      {
!         /* Have a year and month, must be a day: YYYY-MM-DD */
!         if ((fmask & DTK_M(MONTH))
!                  && ((val >= 1) && (val <= 31)))
!         {
!             *tmask = DTK_M(DAY);
!             tm->tm_mday = val;
!         }
!         /* Have a year but no month, must be a month: YYYY-MM-DD */
!         else if ((val >= 1) && (val <= 12))
!         {
!             *tmask = DTK_M(MONTH);
!             tm->tm_mon = val;
!         }
!         else
!             return -1;
      }
!     /* Begin "not year" section */
!     else
      {
!         /* Have no year, no month, and a day, must be a month: DD-MM-YYYY */
!         if ((fmask & DTK_M(DAY)) && (!(fmask & DTK_M(MONTH)))
!                  && ((val >= 1) && (val <= 12)))
!         {
!             *tmask = DTK_M(MONTH);
!             tm->tm_mon = val;
!         }
!         /* Have no year and no month, must be day: DD-MM-YYYY */
!         else if ((!(fmask & DTK_M(MONTH)))
!                  && ((val >= 1) && (val <= 31)))
!         {
!             *tmask = DTK_M(DAY);
!             tm->tm_mday = val;
!         }
!         /* Have no year, a day, and a month, must be a two digit year: DD-MM-YY */
!         else if ((fmask & DTK_M(DAY)) && (fmask & DTK_M(MONTH)))
!         {
!             *tmask = DTK_M(YEAR);
!             tm->tm_year = val;
!             *is2digits = TRUE;
!         }
!         else
!             return -1;
      }

      return 0;
  }    /* DecodeNumber() */




--
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 200306231642

-----BEGIN PGP SIGNATURE-----
Comment: http://www.turnstep.com/pgp.html

iD8DBQE+92crvJuQZxSWSsgRAnw+AJwMZnUrMwa61oZ0/ZJE13+gsPHukgCg6Yz1
lSbJJL1X/k0eH3C096DL/Io=
=o3+o
-----END PGP SIGNATURE-----



Re: Consistent timestamp input

From
Tom Lane
Date:
"Greg Sabino Mullane" <greg@turnstep.com> writes:
> This one bugged me so much, I made a patch for it. It enforces
> consistent interpretation of date input:

This cannot be right can it?  The code used to check EuroDates and now
it doesn't.  ISTM you must have broken either Euro or US format.

Also, I thought that the consensus on -general was that the heuristics
involving looking at the range of the values were a bad idea.  (While
I disagree, I can recognize a lost cause when I see one.)  You've still
got them in there.  ISTM the code ought to assume MM before DD if ISO
or Euro style, otherwise (US style) assume DD before MM, and then reject
if out of range, rather than allowing the range to determine which is
which.

            regards, tom lane

Re: Consistent timestamp input

From
greg@turnstep.com
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


> This cannot be right can it?  The code used to check EuroDates and now
> it doesn't.  ISTM you must have broken either Euro or US format.

I'm not sure of the final consensus on what exactly the behavior should be.

> Also, I thought that the consensus on -general was that the heuristics
> involving looking at the range of the values were a bad idea.  (While
> I disagree, I can recognize a lost cause when I see one.)  You've still
> got them in there.  ISTM the code ought to assume MM before DD if ISO
> or Euro style, otherwise (US style) assume DD before MM, and then reject
> if out of range, rather than allowing the range to determine which is
> which.

The ranges are only in there as an earlier catch of an invalid date - they
no longer are part of the earlier logic which allowed a "pass-through."
They should be removeable with no effect. I'll write up a new patch.
Does this logic seem correct?

if (US) {
  YYYY-MM-DD
  MM-DD-YYYY
}
else {
  YYYY-MM-DD
  DD-MM-YYYY
}

In other words, the US is backwards from the rest of the world.
(as far as MM-DD-YYYY)

Thanks,

- --
Greg Sabino Mullane greg@turnstep.com
PGP Key: 0x14964AC8 200306251031

-----BEGIN PGP SIGNATURE-----
Comment: http://www.turnstep.com/pgp.html

iD8DBQE++bdlvJuQZxSWSsgRArcZAKD4+VO8yK6LeOYszPHL9Kp2Ol4HaQCg4Ovf
wv8M/bvlzeACu6/ow8RpvoQ=
=Dgns
-----END PGP SIGNATURE-----