Consistent timestamp input

Started by Greg Sabino Mullaneabout 23 years ago3 messagespatches
Jump to latest
#1Greg Sabino Mullane
greg@turnstep.com

-----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-----

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Greg Sabino Mullane (#1)
Re: Consistent timestamp input

"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

#3Greg Sabino Mullane
greg@turnstep.com
In reply to: Tom Lane (#2)
Re: Consistent timestamp input

-----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-----