From 9b15b1401482f4354dd0205c607edddb48950ad0 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 24 Nov 2006 22:25:56 +0000 Subject: [PATCH] Revert (too late in beta): Fix to_char() locale handling to honor LC_TIME, not LC_MESSAGES. Euler Taveira de Oliveira --- src/backend/utils/adt/formatting.c | 317 +++++++++++++++++------------ 1 file 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 #include #include -#include +#include #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 -- 2.40.0