summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2006-11-24 22:25:56 +0000
committerBruce Momjian <bruce@momjian.us>2006-11-24 22:25:56 +0000
commit9b15b1401482f4354dd0205c607edddb48950ad0 (patch)
treedb92b4a7c9a6b70f863d3ec20494d02a1f85ef72
parent988a87a03a28146f9a106250e92aa73c43ed8f78 (diff)
downloadpostgresql-9b15b1401482f4354dd0205c607edddb48950ad0.tar.gz
Revert (too late in beta):
Fix to_char() locale handling to honor LC_TIME, not LC_MESSAGES. Euler Taveira de Oliveira
-rw-r--r--src/backend/utils/adt/formatting.c317
1 files changed, 182 insertions, 135 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 93aad1a901..5ce975e2fb 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.114 2006/11/24 15:26:18 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.115 2006/11/24 22:25:56 momjian Exp $
*
*
* Portions Copyright (c) 1999-2006, PostgreSQL Global Development Group
@@ -73,7 +73,7 @@
#include <unistd.h>
#include <math.h>
#include <float.h>
-#include <time.h>
+#include <locale.h>
#include "utils/builtins.h"
#include "utils/date.h"
@@ -83,6 +83,8 @@
#include "utils/numeric.h"
#include "utils/pg_locale.h"
+#define _(x) gettext((x))
+
/* ----------
* Routines type
* ----------
@@ -161,6 +163,7 @@ struct FormatNode
/* ----------
* Full months
+ * This needs to be NLS-localized someday.
* ----------
*/
static char *months_full[] = {
@@ -939,6 +942,10 @@ static NUMCacheEntry *NUM_cache_search(char *str);
static NUMCacheEntry *NUM_cache_getnew(char *str);
static void NUM_cache_remove(NUMCacheEntry *ent);
+static char *localize_month_full(int index);
+static char *localize_month(int index);
+static char *localize_day_full(int index);
+static char *localize_day(int index);
/* ----------
* Fast sequential search, use index for data selection which
@@ -2067,17 +2074,6 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
struct pg_tm *tm = NULL;
TmFromChar *tmfc = NULL;
TmToChar *tmtc = NULL;
- char *save_loc = NULL;
-
- /*
- * Set the LC_TIME only to do some operation (strftime) and then
- * set it back. See pg_locale.c for explanations.
- */
- if (S_TM(suf))
- {
- save_loc = setlocale(LC_TIME, NULL);
- setlocale(LC_TIME, locale_time);
- }
if (is_to_char)
{
@@ -2193,20 +2189,9 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
if (!tm->tm_mon)
return -1;
if (S_TM(suf))
- {
- /*
- * tm_mon in 'pg_tm struct' based on one, but rather POSIX 'tm struct' based on zero.
- * See notes at the top of this file.
- */
- tm->tm_mon = tm->tm_mon - 1;
- strftime(workbuff, sizeof(workbuff), "%B", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
else
- {
strcpy(workbuff, months_full[tm->tm_mon - 1]);
- }
sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, str_toupper(workbuff));
return strlen(p_inout);
@@ -2215,22 +2200,9 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
if (!tm->tm_mon)
return -1;
if (S_TM(suf))
- {
- /*
- * tm_mon in 'pg_tm struct' based on one, but rather POSIX 'tm struct' based on zero.
- * See notes at the top of this file.
- */
- tm->tm_mon = tm->tm_mon - 1;
- strftime(inout, 32, "%B", (struct tm *) tm);
- /* capitalize output */
- inout[0] = pg_toupper((unsigned char) inout[0]);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ sprintf(inout, "%*s", 0, localize_month_full(tm->tm_mon - 1));
else
- {
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
- }
return strlen(p_inout);
case DCH_month:
@@ -2238,20 +2210,9 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
if (!tm->tm_mon)
return -1;
if (S_TM(suf))
- {
- /*
- * tm_mon in 'pg_tm struct' based on one, but rather POSIX 'tm struct' based on zero.
- * See notes at the top of this file.
- */
- tm->tm_mon = tm->tm_mon - 1;
- strftime(inout, 32, "%B", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ sprintf(inout, "%*s", 0, localize_month_full(tm->tm_mon - 1));
else
- {
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
- }
*inout = pg_tolower((unsigned char) *inout);
return strlen(p_inout);
@@ -2260,20 +2221,9 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
if (!tm->tm_mon)
return -1;
if (S_TM(suf))
- {
- /*
- * tm_mon in 'pg_tm struct' based on one, but rather POSIX 'tm struct' based on zero.
- * See notes at the top of this file.
- */
- tm->tm_mon = tm->tm_mon - 1;
- strftime(inout, 32, "%b", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(inout, localize_month(tm->tm_mon - 1));
else
- {
strcpy(inout, months[tm->tm_mon - 1]);
- }
str_toupper(inout);
return strlen(p_inout);
@@ -2282,22 +2232,9 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
if (!tm->tm_mon)
return -1;
if (S_TM(suf))
- {
- /*
- * tm_mon in 'pg_tm struct' based on one, but rather POSIX 'tm struct' based on zero.
- * See notes at the top of this file.
- */
- tm->tm_mon = tm->tm_mon - 1;
- strftime(inout, 32, "%b", (struct tm *) tm);
- /* capitalize output */
- inout[0] = pg_toupper((unsigned char) inout[0]);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(inout, localize_month(tm->tm_mon - 1));
else
- {
strcpy(inout, months[tm->tm_mon - 1]);
- }
return strlen(p_inout);
case DCH_mon:
@@ -2305,20 +2242,9 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
if (!tm->tm_mon)
return -1;
if (S_TM(suf))
- {
- /*
- * tm_mon in 'pg_tm struct' based on one, but rather POSIX 'tm struct' based on zero.
- * See notes at the top of this file.
- */
- tm->tm_mon = tm->tm_mon - 1;
- strftime(inout, 32, "%b", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(inout, localize_month(tm->tm_mon - 1));
else
- {
strcpy(inout, months[tm->tm_mon - 1]);
- }
*inout = pg_tolower((unsigned char) *inout);
return strlen(p_inout);
@@ -2347,92 +2273,52 @@ dch_date(int arg, char *inout, int suf, bool is_to_char, bool is_interval,
case DCH_DAY:
INVALID_FOR_INTERVAL;
if (S_TM(suf))
- {
- strftime(workbuff, sizeof(workbuff), "%A", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(workbuff, localize_day_full(tm->tm_wday));
else
- {
strcpy(workbuff, days[tm->tm_wday]);
- }
sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, str_toupper(workbuff));
return strlen(p_inout);
case DCH_Day:
INVALID_FOR_INTERVAL;
if (S_TM(suf))
- {
- strftime(inout, 32, "%A", (struct tm *) tm);
- /* capitalize output */
- inout[0] = pg_toupper((unsigned char) inout[0]);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));
else
- {
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
- }
return strlen(p_inout);
case DCH_day:
INVALID_FOR_INTERVAL;
if (S_TM(suf))
- {
- strftime(inout, 32, "%A", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));
else
- {
sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
- }
*inout = pg_tolower((unsigned char) *inout);
return strlen(p_inout);
case DCH_DY:
INVALID_FOR_INTERVAL;
if (S_TM(suf))
- {
- strftime(inout, 32, "%a", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(inout, localize_day(tm->tm_wday));
else
- {
strcpy(inout, days_short[tm->tm_wday]);
- }
str_toupper(inout);
return strlen(p_inout);
case DCH_Dy:
INVALID_FOR_INTERVAL;
if (S_TM(suf))
- {
- strftime(inout, 32, "%a", (struct tm *) tm);
- /* capitalize output */
- inout[0] = pg_toupper((unsigned char) inout[0]);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(inout, localize_day(tm->tm_wday));
else
- {
strcpy(inout, days_short[tm->tm_wday]);
- }
return strlen(p_inout);
case DCH_dy:
INVALID_FOR_INTERVAL;
if (S_TM(suf))
- {
- strftime(inout, 32, "%a", (struct tm *) tm);
- /* set it back; see comments in pg_locale.c */
- setlocale(LC_TIME, save_loc);
- }
+ strcpy(inout, localize_day(tm->tm_wday));
else
- {
strcpy(inout, days_short[tm->tm_wday]);
- }
*inout = pg_tolower((unsigned char) *inout);
return strlen(p_inout);
@@ -2974,6 +2860,167 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval)
return res;
}
+static char *
+localize_month_full(int index)
+{
+ char *m = NULL;
+
+ switch (index)
+ {
+ case 0:
+ m = _("January");
+ break;
+ case 1:
+ m = _("February");
+ break;
+ case 2:
+ m = _("March");
+ break;
+ case 3:
+ m = _("April");
+ break;
+ case 4:
+ m = _("May");
+ break;
+ case 5:
+ m = _("June");
+ break;
+ case 6:
+ m = _("July");
+ break;
+ case 7:
+ m = _("August");
+ break;
+ case 8:
+ m = _("September");
+ break;
+ case 9:
+ m = _("October");
+ break;
+ case 10:
+ m = _("November");
+ break;
+ case 11:
+ m = _("December");
+ break;
+ }
+
+ return m;
+}
+
+static char *
+localize_month(int index)
+{
+ char *m = NULL;
+
+ switch (index)
+ {
+ case 0:
+ m = _("Jan");
+ break;
+ case 1:
+ m = _("Feb");
+ break;
+ case 2:
+ m = _("Mar");
+ break;
+ case 3:
+ m = _("Apr");
+ break;
+ case 4:
+ m = _("May");
+ break;
+ case 5:
+ m = _("Jun");
+ break;
+ case 6:
+ m = _("Jul");
+ break;
+ case 7:
+ m = _("Aug");
+ break;
+ case 8:
+ m = _("Sep");
+ break;
+ case 9:
+ m = _("Oct");
+ break;
+ case 10:
+ m = _("Nov");
+ break;
+ case 11:
+ m = _("Dec");
+ break;
+ }
+
+ return m;
+}
+
+static char *
+localize_day_full(int index)
+{
+ char *d = NULL;
+
+ switch (index)
+ {
+ case 0:
+ d = _("Sunday");
+ break;
+ case 1:
+ d = _("Monday");
+ break;
+ case 2:
+ d = _("Tuesday");
+ break;
+ case 3:
+ d = _("Wednesday");
+ break;
+ case 4:
+ d = _("Thursday");
+ break;
+ case 5:
+ d = _("Friday");
+ break;
+ case 6:
+ d = _("Saturday");
+ break;
+ }
+
+ return d;
+}
+
+static char *
+localize_day(int index)
+{
+ char *d = NULL;
+
+ switch (index)
+ {
+ case 0:
+ d = _("Sun");
+ break;
+ case 1:
+ d = _("Mon");
+ break;
+ case 2:
+ d = _("Tue");
+ break;
+ case 3:
+ d = _("Wed");
+ break;
+ case 4:
+ d = _("Thu");
+ break;
+ case 5:
+ d = _("Fri");
+ break;
+ case 6:
+ d = _("Sat");
+ break;
+ }
+
+ return d;
+}
/****************************************************************************
* Public routines