Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2d87eed

Browse files
committed
to_char(): Do not count negative sign as a digit for time values
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
1 parent 6d8b2aa commit 2d87eed

File tree

3 files changed

+24
-16
lines changed

3 files changed

+24
-16
lines changed

src/backend/utils/adt/formatting.c

+18-10
Original file line numberDiff line numberDiff line change
@@ -2426,27 +2426,30 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
24262426
* display time as shown on a 12-hour clock, even for
24272427
* intervals
24282428
*/
2429-
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2,
2429+
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
24302430
tm->tm_hour % (HOURS_PER_DAY / 2) == 0 ? HOURS_PER_DAY / 2 :
24312431
tm->tm_hour % (HOURS_PER_DAY / 2));
24322432
if (S_THth(n->suffix))
24332433
str_numth(s, s, S_TH_TYPE(n->suffix));
24342434
s += strlen(s);
24352435
break;
24362436
case DCH_HH24:
2437-
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_hour);
2437+
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_hour >= 0) ? 2 : 3,
2438+
tm->tm_hour);
24382439
if (S_THth(n->suffix))
24392440
str_numth(s, s, S_TH_TYPE(n->suffix));
24402441
s += strlen(s);
24412442
break;
24422443
case DCH_MI:
2443-
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_min);
2444+
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_min >= 0) ? 2 : 3,
2445+
tm->tm_min);
24442446
if (S_THth(n->suffix))
24452447
str_numth(s, s, S_TH_TYPE(n->suffix));
24462448
s += strlen(s);
24472449
break;
24482450
case DCH_SS:
2449-
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_sec);
2451+
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_sec >= 0) ? 2 : 3,
2452+
tm->tm_sec);
24502453
if (S_THth(n->suffix))
24512454
str_numth(s, s, S_TH_TYPE(n->suffix));
24522455
s += strlen(s);
@@ -2503,7 +2506,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25032506
break;
25042507
case DCH_OF:
25052508
INVALID_FOR_INTERVAL;
2506-
sprintf(s, "%+0*d", S_FM(n->suffix) ? 0 : 3, (int) tm->tm_gmtoff / SECS_PER_HOUR);
2509+
sprintf(s, "%+0*d", S_FM(n->suffix) ? 0 : (tm->tm_gmtoff >= 0) ? 3 : 4,
2510+
(int) tm->tm_gmtoff / SECS_PER_HOUR);
25072511
s += strlen(s);
25082512
if ((int) tm->tm_gmtoff % SECS_PER_HOUR != 0)
25092513
{
@@ -2653,7 +2657,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
26532657
s += strlen(s);
26542658
break;
26552659
case DCH_MM:
2656-
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, tm->tm_mon);
2660+
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (tm->tm_mon >= 0) ? 2 : 3,
2661+
tm->tm_mon);
26572662
if (S_THth(n->suffix))
26582663
str_numth(s, s, S_TH_TYPE(n->suffix));
26592664
s += strlen(s);
@@ -2828,7 +2833,7 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
28282833
i = tm->tm_year / 100 - 1;
28292834
}
28302835
if (i <= 99 && i >= -99)
2831-
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : 2, i);
2836+
sprintf(s, "%0*d", S_FM(n->suffix) ? 0 : (i >= 0) ? 2 : 3, i);
28322837
else
28332838
sprintf(s, "%d", i);
28342839
if (S_THth(n->suffix))
@@ -2846,7 +2851,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
28462851
case DCH_YYYY:
28472852
case DCH_IYYY:
28482853
sprintf(s, "%0*d",
2849-
S_FM(n->suffix) ? 0 : 4,
2854+
S_FM(n->suffix) ? 0 :
2855+
(ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 4 : 5,
28502856
(n->key->id == DCH_YYYY ?
28512857
ADJUST_YEAR(tm->tm_year, is_interval) :
28522858
ADJUST_YEAR(date2isoyear(tm->tm_year,
@@ -2860,7 +2866,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
28602866
case DCH_YYY:
28612867
case DCH_IYY:
28622868
sprintf(s, "%0*d",
2863-
S_FM(n->suffix) ? 0 : 3,
2869+
S_FM(n->suffix) ? 0 :
2870+
(ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 3 : 4,
28642871
(n->key->id == DCH_YYY ?
28652872
ADJUST_YEAR(tm->tm_year, is_interval) :
28662873
ADJUST_YEAR(date2isoyear(tm->tm_year,
@@ -2874,7 +2881,8 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
28742881
case DCH_YY:
28752882
case DCH_IY:
28762883
sprintf(s, "%0*d",
2877-
S_FM(n->suffix) ? 0 : 2,
2884+
S_FM(n->suffix) ? 0 :
2885+
(ADJUST_YEAR(tm->tm_year, is_interval) >= 0) ? 2 : 3,
28782886
(n->key->id == DCH_YY ?
28792887
ADJUST_YEAR(tm->tm_year, is_interval) :
28802888
ADJUST_YEAR(date2isoyear(tm->tm_year,

src/test/regress/expected/timestamp.out

+3-3
Original file line numberDiff line numberDiff line change
@@ -948,8 +948,8 @@ SELECT '' AS to_char_2, to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth F
948948

949949
SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
950950
FROM TIMESTAMP_TBL;
951-
to_char_3 | to_char
952-
-----------+-------------------------------------------------
951+
to_char_3 | to_char
952+
-----------+--------------------------------------------------
953953
|
954954
|
955955
| 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')
992992
| 1,997 1997 997 97 7 20 1 02 07 045 14 6 2450494
993993
| 1,997 1997 997 97 7 20 1 02 07 046 15 7 2450495
994994
| 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496
995-
| 0,097 0097 097 97 7 -1 1 02 07 047 16 3 1686042
995+
| 0,097 0097 097 97 7 -01 1 02 07 047 16 3 1686042
996996
| 0,097 0097 097 97 7 01 1 02 07 047 16 7 1756536
997997
| 0,597 0597 597 97 7 06 1 02 07 047 16 5 1939157
998998
| 1,097 1097 097 97 7 11 1 02 07 047 16 3 2121778

src/test/regress/expected/timestamptz.out

+3-3
Original file line numberDiff line numberDiff line change
@@ -1029,8 +1029,8 @@ SELECT '' AS to_char_2, to_char(d1, 'FMDAY FMDay FMday FMMONTH FMMonth FMmonth F
10291029

10301030
SELECT '' AS to_char_3, to_char(d1, 'Y,YYY YYYY YYY YY Y CC Q MM WW DDD DD D J')
10311031
FROM TIMESTAMPTZ_TBL;
1032-
to_char_3 | to_char
1033-
-----------+-------------------------------------------------
1032+
to_char_3 | to_char
1033+
-----------+--------------------------------------------------
10341034
|
10351035
|
10361036
| 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')
10741074
| 1,997 1997 997 97 7 20 1 02 07 045 14 6 2450494
10751075
| 1,997 1997 997 97 7 20 1 02 07 046 15 7 2450495
10761076
| 1,997 1997 997 97 7 20 1 02 07 047 16 1 2450496
1077-
| 0,097 0097 097 97 7 -1 1 02 07 047 16 3 1686042
1077+
| 0,097 0097 097 97 7 -01 1 02 07 047 16 3 1686042
10781078
| 0,097 0097 097 97 7 01 1 02 07 047 16 7 1756536
10791079
| 0,597 0597 597 97 7 06 1 02 07 047 16 5 1939157
10801080
| 1,097 1097 097 97 7 11 1 02 07 047 16 3 2121778

0 commit comments

Comments
 (0)