Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)