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

Lines changed: 18 additions & 10 deletions
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

Lines changed: 3 additions & 3 deletions
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

Lines changed: 3 additions & 3 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy