diff options
author | Bruce Momjian <bruce@momjian.us> | 2005-12-03 16:45:23 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 2005-12-03 16:45:23 +0000 |
commit | dfdec6044798adfb167c39c12a00c1bbb451a0b0 (patch) | |
tree | 156445a7fe2723cf1822fd18b6525291070cb789 | |
parent | 4ed2e803ef4580ed590f310574b9d6587aaa7231 (diff) | |
download | postgresql-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.sgml | 10 | ||||
-rw-r--r-- | src/backend/utils/adt/formatting.c | 36 |
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. >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); |