]> granicus.if.org Git - postgresql/commitdiff
to_char(): Do not count negative sign as a digit for time values
authorBruce Momjian <bruce@momjian.us>
Tue, 6 Oct 2015 00:51:46 +0000 (20:51 -0400)
committerBruce Momjian <bruce@momjian.us>
Tue, 6 Oct 2015 00:51:46 +0000 (20:51 -0400)
For time masks, like HH24, MI, SS, CC, MM, do not count the negative
sign as part of the zero-padding length specified by the mask, e.g. have
to_char('-4 years'::interval, 'YY') return '-04', not '-4'.

Report by Craig Ringer

src/backend/utils/adt/formatting.c
src/test/regress/expected/timestamp.out
src/test/regress/expected/timestamptz.out

index 5391ea0bf0ba83b27f2d33ddfe7761cb323a009b..5b09de32efc66d3ac07c559837ff101c45324f04 100644 (file)
@@ -2426,7 +2426,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                                 * display time as shown on a 12-hour clock, even for
                                 * intervals
                                 */
-                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2,
+                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
                                 tm->tm_hour % (HOURS_PER_DAY / 2) == 0 ? HOURS_PER_DAY / 2 :
                                                tm->tm_hour % (HOURS_PER_DAY / 2));
                                if (S_THth(n->suffix))
@@ -2434,19 +2434,22 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                                s += strlen(s);
                                break;
                        case DCH_HH24:
-                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_hour);
+                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
+                                               tm->tm_hour);
                                if (S_THth(n->suffix))
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
                                s += strlen(s);
                                break;
                        case DCH_MI:
-                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_min);
+                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_min >= 0) ? 2 : 3,
+                                               tm->tm_min);
                                if (S_THth(n->suffix))
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
                                s += strlen(s);
                                break;
                        case DCH_SS:
-                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_sec);
+                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_sec >= 0) ? 2 : 3,
+                                               tm->tm_sec);
                                if (S_THth(n->suffix))
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
                                s += strlen(s);
@@ -2503,7 +2506,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                                break;
                        case DCH_OF:
                                INVALID_FOR_INTERVAL;
-                               sprintf(s, "%+0*d", S_FM(n->suffix) ? 0 : 3, (int) tm->tm_gmtoff / SECS_PER_HOUR);
+                               sprintf(s, "%+0*d", S_FM(n->suffix) ? 0 : (tm->tm_gmtoff >= 0) ? 3 : 4,
+                                               (int) tm->tm_gmtoff / SECS_PER_HOUR);
                                s += strlen(s);
                                if ((int) tm->tm_gmtoff % SECS_PER_HOUR != 0)
                                {
@@ -2653,7 +2657,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                                s += strlen(s);
                                break;
                        case DCH_MM:
-                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_mon);
+                               sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_mon >= 0) ? 2 : 3,
+                                               tm->tm_mon);
                                if (S_THth(n->suffix))
                                        str_numth(s, s, S_TH_TYPE(n->suffix));
                                s += strlen(s);
@@ -2828,7 +2833,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                                                i = tm->tm_year / 100 - 1;
                                }
                                if (i <= 99 && i >= -99)
-                                       sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, i);
+                                       sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (i >= 0) ? 2 : 3, i);
                                else
                                        sprintf(s, "%d", i);
                                if (S_THth(n->suffix))
@@ -2846,7 +2851,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                        case DCH_YYYY:
                        case DCH_IYYY:
                                sprintf(s, "%0*d",
-                                               S_FM(n->suffix) ? 0 : 4,
+                                               S_FM(n->suffix) ? 0 :
+                                               (ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 4 : 5,
                                                (n->key->id == DCH_YYYY ?
                                                 ADJUST_YEAR(tm->tm_year, is_interval) :
                                                 ADJUST_YEAR(date2isoyear(tm->tm_year,
@@ -2860,7 +2866,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                        case DCH_YYY:
                        case DCH_IYY:
                                sprintf(s, "%0*d",
-                                               S_FM(n->suffix) ? 0 : 3,
+                                               S_FM(n->suffix) ? 0 :
+                                               (ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 3 : 4,
                                                (n->key->id == DCH_YYY ?
                                                 ADJUST_YEAR(tm->tm_year, is_interval) :
                                                 ADJUST_YEAR(date2isoyear(tm->tm_year,
@@ -2874,7 +2881,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
                        case DCH_YY:
                        case DCH_IY:
                                sprintf(s, "%0*d",
-                                               S_FM(n->suffix) ? 0 : 2,
+                                               S_FM(n->suffix) ? 0 :
+                                               (ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 2 : 3,
                                                (n->key->id == DCH_YY ?
                                                 ADJUST_YEAR(tm->tm_year, is_interval) :
                                                 ADJUST_YEAR(date2isoyear(tm->tm_year,
index a092fc25eb7db04d11207ae1905ced54fb62563a..e9f5e7790f5b798618aba63bd0c47d99712a3dc6 100644 (file)
@@ -948,8 +948,8 @@ SELECT '' AS to_char_2, to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth F
 
 SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
    FROM TIMESTAMP_TBL;
- to_char_3 |                     to_char                     
------------+-------------------------------------------------
+ to_char_3 |                     to_char                      
+-----------+--------------------------------------------------
            | 
            | 
            | 1,970 1970 970 70 0 20 1 01 01 001 01 5 2440588
@@ -992,7 +992,7 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
            | 1,997 1997 997 97 7 20 1 02 07 045 14 6 2450494
            | 1,997 1997 997 97 7 20 1 02 07 046 15 7 2450495
            | 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496
-           | 0,097 0097 097 97 7 -1 1 02 07 047 16 3 1686042
+           | 0,097 0097 097 97 7 -01 1 02 07 047 16 3 1686042
            | 0,097 0097 097 97 7 01 1 02 07 047 16 7 1756536
            | 0,597 0597 597 97 7 06 1 02 07 047 16 5 1939157
            | 1,097 1097 097 97 7 11 1 02 07 047 16 3 2121778
index e5a21305c006cb675c48732199e1e4363c99832d..40a22540e559265b75bcb931e966e91bb1ecd467 100644 (file)
@@ -1029,8 +1029,8 @@ SELECT '' AS to_char_2, to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth F
 
 SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
    FROM TIMESTAMPTZ_TBL;
- to_char_3 |                     to_char                     
------------+-------------------------------------------------
+ to_char_3 |                     to_char                      
+-----------+--------------------------------------------------
            | 
            | 
            | 1,969 1969 969 69 9 20 4 12 53 365 31 4 2440587
@@ -1074,7 +1074,7 @@ SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
            | 1,997 1997 997 97 7 20 1 02 07 045 14 6 2450494
            | 1,997 1997 997 97 7 20 1 02 07 046 15 7 2450495
            | 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496
-           | 0,097 0097 097 97 7 -1 1 02 07 047 16 3 1686042
+           | 0,097 0097 097 97 7 -01 1 02 07 047 16 3 1686042
            | 0,097 0097 097 97 7 01 1 02 07 047 16 7 1756536
            | 0,597 0597 597 97 7 06 1 02 07 047 16 5 1939157
            | 1,097 1097 097 97 7 11 1 02 07 047 16 3 2121778