aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2005-12-03 16:45:23 +0000
committerBruce Momjian <bruce@momjian.us>2005-12-03 16:45:23 +0000
commitdfdec6044798adfb167c39c12a00c1bbb451a0b0 (patch)
tree156445a7fe2723cf1822fd18b6525291070cb789
parent4ed2e803ef4580ed590f310574b9d6587aaa7231 (diff)
downloadpostgresql-dfdec6044798adfb167c39c12a00c1bbb451a0b0.tar.gz
postgresql-dfdec6044798adfb167c39c12a00c1bbb451a0b0.zip
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.
-rw-r--r--doc/src/sgml/func.sgml10
-rw-r--r--src/backend/utils/adt/formatting.c36
2 files changed, 25 insertions, 21 deletions
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 0148d72d22d..dc927737c31 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1,5 +1,5 @@
<!--
-$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.291.2.2 2005/11/28 23:19:03 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.291.2.3 2005/12/03 16:45:22 momjian Exp $
PostgreSQL documentation
-->
@@ -4749,6 +4749,14 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
<function>extract</function> function.
</para>
</listitem>
+
+ <listitem>
+ <para><function>to_char(interval)</function> formats <literal>HH</> and
+ <literal>HH12</> as hours in a single day, while <literal>HH24</>
+ can output hours exceeding a single day, e.g. &gt;24.
+ </para>
+ </listitem>
+
</itemizedlist>
</para>
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index b02fdfeff5d..96b99730dd8 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,7 +1,7 @@
/* -----------------------------------------------------------------------
* formatting.c
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.101.2.1 2005/11/22 18:23:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.101.2.2 2005/12/03 16:45:23 momjian Exp $
*
*
* Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group
@@ -434,6 +434,10 @@ do { \
tmtcTzn(_X) = NULL; \
} while(0)
+/*
+ * to_char(time) appears to to_char() as an interval, so this check
+ * is really for interval and time data types.
+ */
#define INVALID_FOR_INTERVAL \
do { \
if (is_interval) \
@@ -1722,11 +1726,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
{
case DCH_A_M:
case DCH_P_M:
- INVALID_FOR_INTERVAL;
if (is_to_char)
{
- strcpy(inout, ((tm->tm_hour > 11
- && tm->tm_hour < HOURS_PER_DAY) ? P_M_STR : A_M_STR));
+ strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
+ ? P_M_STR : A_M_STR);
return strlen(p_inout);
}
else
@@ -1742,11 +1745,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
break;
case DCH_AM:
case DCH_PM:
- INVALID_FOR_INTERVAL;
if (is_to_char)
{
- strcpy(inout, ((tm->tm_hour > 11
- && tm->tm_hour < HOURS_PER_DAY) ? PM_STR : AM_STR));
+ strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
+ ? PM_STR : AM_STR);
return strlen(p_inout);
}
else
@@ -1762,11 +1764,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
break;
case DCH_a_m:
case DCH_p_m:
- INVALID_FOR_INTERVAL;
if (is_to_char)
{
- strcpy(inout, ((tm->tm_hour > 11
- && tm->tm_hour < HOURS_PER_DAY) ? p_m_STR : a_m_STR));
+ strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
+ ? p_m_STR : a_m_STR);
return strlen(p_inout);
}
else
@@ -1782,11 +1783,10 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
break;
case DCH_am:
case DCH_pm:
- INVALID_FOR_INTERVAL;
if (is_to_char)
{
- strcpy(inout, ((tm->tm_hour > 11
- && tm->tm_hour < HOURS_PER_DAY) ? pm_STR : am_STR));
+ strcpy(inout, (tm->tm_hour % HOURS_PER_DAY >= HOURS_PER_DAY / 2)
+ ? pm_STR : am_STR);
return strlen(p_inout);
}
else
@@ -1804,12 +1804,9 @@ dch_time(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
case DCH_HH12:
if (is_to_char)
{
- if (is_interval)
- sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2, tm->tm_hour);
- else
- sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,
- tm->tm_hour == 0 ? 12 :
- tm->tm_hour < 13 ? tm->tm_hour : tm->tm_hour - 12);
+ sprintf(inout, "%0*d", S_FM(suf) ? 0 : 2,
+ tm->tm_hour % (HOURS_PER_DAY / 2) == 0 ? 12 :
+ tm->tm_hour % (HOURS_PER_DAY / 2));
if (S_THth(suf))
str_numth(p_inout, inout, 0);
return strlen(p_inout);
@@ -2312,7 +2309,6 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
}
break;
case DCH_D:
- INVALID_FOR_INTERVAL;
if (is_to_char)
{
sprintf(inout, "%d", tm->tm_wday + 1);