Обсуждение: patch for datetime.c
[root@d1 ~/postgresql-7.1/src/backend/utils/adt] diff -C 3 datetime.c.orig datetime.c *** datetime.c.orig Thu May 3 21:16:37 2001 --- datetime.c Thu May 3 21:19:51 2001 *************** *** 2087,2092 **** --- 2087,2096 ---- sec = (tm->tm_sec + fsec); + if (sec >= 59.995) + sec = 59.99; /* Round down to avoid times like 2001-05-03 21:18:60.00-04 */ + + switch (style) { /* compatible with ISO date formats */ -- Joseph Shraibman jks@selectacast.net Increase signal to noise ratio. http://www.targabot.com
Joseph Shraibman <jks@selectacast.net> writes: > [root@d1 ~/postgresql-7.1/src/backend/utils/adt] diff -C 3 > datetime.c.orig datetime.c > *** datetime.c.orig Thu May 3 21:16:37 2001 > --- datetime.c Thu May 3 21:19:51 2001 > *************** > *** 2087,2092 **** > --- 2087,2096 ---- > sec = (tm->tm_sec + fsec); > + if (sec >= 59.995) > + sec = 59.99; /* Round down to avoid times like > 2001-05-03 21:18:60.00-04 */ > + > + > switch (style) > { > /* compatible with ISO date formats */ This is a horrid solution. The correct solution is to round the original timestamp to two fractional digits before it's ever broken down into y/m/d/h/m/s. At least if you only want two digits of precision. I think Thomas has been resisting making that change because he wants to allow displaying more than two digits, instead. BTW, is there really only one routine with this problem? regards, tom lane
Tom Lane wrote: > > Joseph Shraibman <jks@selectacast.net> writes: > > [root@d1 ~/postgresql-7.1/src/backend/utils/adt] diff -C 3 > > datetime.c.orig datetime.c > > *** datetime.c.orig Thu May 3 21:16:37 2001 > > --- datetime.c Thu May 3 21:19:51 2001 > > *************** > > *** 2087,2092 **** > > --- 2087,2096 ---- > > > sec = (tm->tm_sec + fsec); > > > + if (sec >= 59.995) > > + sec = 59.99; /* Round down to avoid times like > > 2001-05-03 21:18:60.00-04 */ > > + > > + > > switch (style) > > { > > /* compatible with ISO date formats */ > > This is a horrid solution. Well not horrid, but stopgap. There needed to be soemthing that kept there from being 60 seconds in the output. > > The correct solution is to round the original timestamp to two > fractional digits before it's ever broken down into y/m/d/h/m/s. I was afraid to modify the timestamp object. I didn't know what side affects that might have. And I wasn't sure how to create a timestamp from another timestamp. > > At least if you only want two digits of precision. I think Thomas > has been resisting making that change because he wants to allow > displaying more than two digits, instead. > That was the other thing I considered, but I thought two digits was there because it was standard. > BTW, is there really only one routine with this problem? > Err, sort of. There is another method in the same file that operates on time and appears to have the same bug, but times aren't supposed to have fractional seconds. playpen=# select '5:33:59.999'::time; ?column? ---------- 05:33:59 (1 row) So I'm not sure if that other function is a problem or not. -- Joseph Shraibman jks@selectacast.net Increase signal to noise ratio. http://www.targabot.com
Joseph Shraibman <jks@selectacast.net> writes: > Well not horrid, but stopgap. There needed to be soemthing that kept > there from being 60 seconds in the output. Don't forget that there are minutes with 61 seconds in UTC, due to leap seconds. See, e.g., http://cr.yp.to/proto/utctai.html For example, 1997-06-30 23:59:60 is a correct time in UTC. Many free Unix systems will return times like this when the time zone is set appropriately. For example, on my Red Hat 6.1 system, this: TZ=right/UTC date --date='June 30, 1997 23:59:60 +0000' will print this: Mon Jun 30 23:59:60 UTC 1997 (for comparison: > TZ=posix/UTC date --date='June 30, 1997 23:59:60 +0000' Tue Jul 1 00:00:00 UTC 1997 ) Ian ---------------------------(end of broadcast)--------------------------- TIP 231: There are times when truth is stranger than fiction and lunch time is one of them.