patch for 60 seconds bug - Mailing list pgsql-patches
From | Joseph Shraibman |
---|---|
Subject | patch for 60 seconds bug |
Date | |
Msg-id | 3B7B2DEC.4070700@selectacast.net Whole thread Raw |
Responses |
Re: patch for 60 seconds bug
|
List | pgsql-patches |
This patch fixes the problem of doing: select '2001-08-15 23:59:59.996'::timestamp; ... and getting a string with 60 in the seconds field. This only fixes the method EncodeDateTime(), the fix should be applied to EncodeTimeOnly() as well. (I didn't do it because I thought that you might want to make this prettier before applying). I was afraid to modify the fields in the passed in tm object. Logically since it is only output by this method even if internally it was changed it would have to go through this method again to be output anyway, but I didn't want to mess with it. This should be in the next 7.1.x release so when people dump from 7.1 to upgrade to 7.2 they won't have invalid data. Interestingly: select '2001-08-15 23:59:59.995'::timestamp; use to output: 2001-08-15 23:59:59.99-04 on my system before I made this change. Is this the result of some funkiness in my libc? I'm using a redhat 6.2ish system with glibc 2.1.3 *** datetime.c.orig Wed Aug 15 21:00:05 2001 --- datetime.c Wed Aug 15 22:05:56 2001 *************** *** 2080,2086 **** { int day, hour, ! min; double sec; if ((tm->tm_mon < 1) || (tm->tm_mon > 12)) --- 2080,2091 ---- { int day, hour, ! min, ! tmyear, ! tmmon, ! tmmday, ! tmhour, ! tmmin; double sec; if ((tm->tm_mon < 1) || (tm->tm_mon > 12)) *************** *** 2088,2093 **** --- 2093,2126 ---- sec = (tm->tm_sec + fsec); + /* code to round the datetime so outputs with 60 seconds dont happen + I don't want to modify the tm values bec. I don't know if there would be side affects + so I created seperate variables. + I left BC dates alone. + */ + tmyear = tm->tm_year; + tmmon = tm->tm_mon; + tmmday = tm->tm_mday; + tmhour = tm->tm_hour; + tmmin = tm->tm_min; + if (sec >= 59.995){ + sec = 0; + if (++tmmin > 59){ + tmmin = 0; + if (++tmhour > 23){ + tmhour = 0; + if (++tmmday > day_tab[isleap(tmyear)][tmmon - 1]){ + tmmday = 1; + if (++tmmon > 12){ + tmmon = 1; + tmyear++;/* what about BC? */ + } + } + } + } + }; + + switch (style) { /* compatible with ISO date formats */ *************** *** 2096,2102 **** if (tm->tm_year > 0) { sprintf(str, "%04d-%02d-%02d %02d:%02d:", ! tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min); sprintf((str + strlen(str)), ((fsec != 0) ? "%05.2f" : "%02.0f"), sec); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) --- 2129,2135 ---- if (tm->tm_year > 0) { sprintf(str, "%04d-%02d-%02d %02d:%02d:", ! tmyear, tmmon, tmmday, tmhour, tmmin); sprintf((str + strlen(str)), ((fsec != 0) ? "%05.2f" : "%02.0f"), sec); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) *************** *** 2129,2158 **** /* compatible with Oracle/Ingres date formats */ case USE_SQL_DATES: if (EuroDates) ! sprintf(str, "%02d/%02d", tm->tm_mday, tm->tm_mon); else ! sprintf(str, "%02d/%02d", tm->tm_mon, tm->tm_mday); if (tm->tm_year > 0) { sprintf((str + 5), "/%04d %02d:%02d:%05.2f", ! tm->tm_year, tm->tm_hour, tm->tm_min, sec); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); } else sprintf((str + 5), "/%04d %02d:%02d %s", ! -(tm->tm_year - 1), tm->tm_hour, tm->tm_min, "BC"); break; /* German variant on European style */ case USE_GERMAN_DATES: ! sprintf(str, "%02d.%02d", tm->tm_mday, tm->tm_mon); if (tm->tm_year > 0) { sprintf((str + 5), ".%04d %02d:%02d:%05.2f", ! tm->tm_year, tm->tm_hour, tm->tm_min, sec); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); --- 2162,2191 ---- /* compatible with Oracle/Ingres date formats */ case USE_SQL_DATES: if (EuroDates) ! sprintf(str, "%02d/%02d", tmmday, tmmon); else ! sprintf(str, "%02d/%02d", tmmon, tmmday); if (tm->tm_year > 0) { sprintf((str + 5), "/%04d %02d:%02d:%05.2f", ! tmyear, tmhour, tmmin, sec); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); } else sprintf((str + 5), "/%04d %02d:%02d %s", ! -(tm->tm_year - 1), tmhour, tmmin, "BC"); break; /* German variant on European style */ case USE_GERMAN_DATES: ! sprintf(str, "%02d.%02d", tmmday, tmmon); if (tm->tm_year > 0) { sprintf((str + 5), ".%04d %02d:%02d:%05.2f", ! tmyear, tmhour, tmmin, sec); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); *************** *** 2165,2193 **** /* backward-compatible with traditional Postgres abstime dates */ case USE_POSTGRES_DATES: default: ! day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday); tm->tm_wday = j2day(day); strncpy(str, days[tm->tm_wday], 3); strcpy((str + 3), " "); if (EuroDates) ! sprintf((str + 4), "%02d %3s", tm->tm_mday, months[tm->tm_mon - 1]); else ! sprintf((str + 4), "%3s %02d", months[tm->tm_mon - 1], tm->tm_mday); if (tm->tm_year > 0) { ! sprintf((str + 10), " %02d:%02d", tm->tm_hour, tm->tm_min); if (fsec != 0) { ! sprintf((str + 16), ":%05.2f %04d", sec, tm->tm_year); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); } else { ! sprintf((str + 16), ":%02.0f %04d", sec, tm->tm_year); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); } --- 2198,2226 ---- /* backward-compatible with traditional Postgres abstime dates */ case USE_POSTGRES_DATES: default: ! day = date2j(tmyear, tmmon, tmmday); tm->tm_wday = j2day(day); strncpy(str, days[tm->tm_wday], 3); strcpy((str + 3), " "); if (EuroDates) ! sprintf((str + 4), "%02d %3s", tmmday, months[tmmon - 1]); else ! sprintf((str + 4), "%3s %02d", months[tmmon - 1], tmmday); if (tm->tm_year > 0) { ! sprintf((str + 10), " %02d:%02d", tmhour, tmmin); if (fsec != 0) { ! sprintf((str + 16), ":%05.2f %04d", sec, tmyear); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); } else { ! sprintf((str + 16), ":%02.0f %04d", sec, tmyear); if ((*tzn != NULL) && (tm->tm_isdst >= 0)) sprintf((str + strlen(str)), " %.*s", MAXTZLEN, *tzn); } -- Joseph Shraibman jks@selectacast.net Increase signal to noise ratio. http://www.targabot.com
pgsql-patches by date: