Skip to content

Commit d20901a

Browse files
committed
Allow to_char(interval) and to_char(time) to use AM/PM specifications.
Map them to a single day, so '30 hours' is 'AM'. Have to_char(interval) and to_char(time) use "HH", "HH12" as 12-hour intervals, rather than bypass and print the full interval hours. This is neeeded because to_char(time) is mapped to interval in this function. Intervals should use "HH24", and document suggestion. Allow "D" format specifiers for interval/time.
1 parent eb339c7 commit d20901a

File tree

2 files changed

+25
-21
lines changed

2 files changed

+25
-21
lines changed

doc/src/sgml/func.sgml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.296 2005/11/28 23:18:48 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.297 2005/12/03 16:45:05 momjian Exp $
33
PostgreSQL documentation
44
-->
55

@@ -4749,6 +4749,14 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
47494749
<function>extract</function> function.
47504750
</para>
47514751
</listitem>
4752+
4753+
<listitem>
4754+
<para><function>to_char(interval)</function> formats <literal>HH</> and
4755+
<literal>HH12</> as hours in a single day, while <literal>HH24</>
4756+
can output hours exceeding a single day, e.g. &gt;24.
4757+
</para>
4758+
</listitem>
4759+
47524760
</itemizedlist>
47534761
</para>
47544762

src/backend/utils/adt/formatting.c

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.102 2005/11/22 18:17:22 momjian Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.103 2005/12/03 16:45:06 momjian Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group
@@ -434,6 +434,10 @@ do { \
434434
tmtcTzn(_X) = NULL; \
435435
} while(0)
436436

437+
/*
438+
* to_char(time) appears to to_char() as an interval, so this check
439+
* is really for interval and time data types.
440+
*/
437441
#define INVALID_FOR_INTERVAL \
438442
do { \
439443
if (is_interval) \
@@ -1722,11 +1726,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
17221726
{
17231727
case DCH_A_M:
17241728
case DCH_P_M:
1725-
INVALID_FOR_INTERVAL;
17261729
if (is_to_char)
17271730
{
1728-
strcpy(inout, ((tm->tm_hour > 11
1729-
&& tm->tm_hour < HOURS_PER_DAY) ? P_M_STR : A_M_STR));
1731+
strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
1732+
? P_M_STR : A_M_STR);
17301733
return strlen(p_inout);
17311734
}
17321735
else
@@ -1742,11 +1745,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
17421745
break;
17431746
case DCH_AM:
17441747
case DCH_PM:
1745-
INVALID_FOR_INTERVAL;
17461748
if (is_to_char)
17471749
{
1748-
strcpy(inout, ((tm->tm_hour > 11
1749-
&& tm->tm_hour < HOURS_PER_DAY) ? PM_STR : AM_STR));
1750+
strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
1751+
? PM_STR : AM_STR);
17501752
return strlen(p_inout);
17511753
}
17521754
else
@@ -1762,11 +1764,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
17621764
break;
17631765
case DCH_a_m:
17641766
case DCH_p_m:
1765-
INVALID_FOR_INTERVAL;
17661767
if (is_to_char)
17671768
{
1768-
strcpy(inout, ((tm->tm_hour > 11
1769-
&& tm->tm_hour < HOURS_PER_DAY) ? p_m_STR : a_m_STR));
1769+
strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
1770+
? p_m_STR : a_m_STR);
17701771
return strlen(p_inout);
17711772
}
17721773
else
@@ -1782,11 +1783,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
17821783
break;
17831784
case DCH_am:
17841785
case DCH_pm:
1785-
INVALID_FOR_INTERVAL;
17861786
if (is_to_char)
17871787
{
1788-
strcpy(inout, ((tm->tm_hour > 11
1789-
&& tm->tm_hour < HOURS_PER_DAY) ? pm_STR : am_STR));
1788+
strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
1789+
? pm_STR : am_STR);
17901790
return strlen(p_inout);
17911791
}
17921792
else
@@ -1804,12 +1804,9 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
18041804
case DCH_HH12:
18051805
if (is_to_char)
18061806
{
1807-
if (is_interval)
1808-
sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour);
1809-
else
1810-
sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,
1811-
tm->tm_hour == 0 ? 12 :
1812-
tm->tm_hour < 13 ? tm->tm_hour : tm->tm_hour - 12);
1807+
sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,
1808+
tm->tm_hour % (HOURS_PER_DAY / 2) == 0 ? 12 :
1809+
tm->tm_hour % (HOURS_PER_DAY / 2));
18131810
if (S_THth(suf))
18141811
str_numth(p_inout, inout, 0);
18151812
return strlen(p_inout);
@@ -2312,7 +2309,6 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
23122309
}
23132310
break;
23142311
case DCH_D:
2315-
INVALID_FOR_INTERVAL;
23162312
if (is_to_char)
23172313
{
23182314
sprintf(inout, "%d", tm->tm_wday + 1);

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