summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/pg_locale.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/pg_locale.c')
-rw-r--r--src/backend/utils/adt/pg_locale.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 9072cb54f2..dfc6c886a5 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -4,7 +4,7 @@
*
* Portions Copyright (c) 2002-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.40 2008/01/01 19:45:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.41 2008/05/19 18:08:16 tgl Exp $
*
*-----------------------------------------------------------------------
*/
@@ -48,20 +48,31 @@
#include "postgres.h"
#include <locale.h>
+#include <time.h>
#include "catalog/pg_control.h"
+#include "utils/memutils.h"
#include "utils/pg_locale.h"
-/* GUC storage area */
+#define MAX_L10N_DATA 80
+
+/* GUC settings */
char *locale_messages;
char *locale_monetary;
char *locale_numeric;
char *locale_time;
+/* lc_time localization cache */
+char *localized_abbrev_days[7];
+char *localized_full_days[7];
+char *localized_abbrev_months[12];
+char *localized_full_months[12];
+
/* indicates whether locale information cache is valid */
static bool CurrentLocaleConvValid = false;
+static bool CurrentLCTimeValid = false;
/* Environment variable storage area */
@@ -209,7 +220,10 @@ locale_xxx_assign(int category, const char *value, bool doit, GucSource source)
/* need to reload cache next time? */
if (doit && value != NULL)
+ {
CurrentLocaleConvValid = false;
+ CurrentLCTimeValid = false;
+ }
return value;
}
@@ -424,3 +438,78 @@ PGLC_localeconv(void)
CurrentLocaleConvValid = true;
return &CurrentLocaleConv;
}
+
+
+/*
+ * Update the lc_time localization cache variables if needed.
+ */
+void
+cache_locale_time(void)
+{
+ char *save_lc_time;
+ time_t timenow;
+ struct tm *timeinfo;
+ char buf[MAX_L10N_DATA];
+ char *ptr;
+ int i;
+
+ /* did we do this already? */
+ if (CurrentLCTimeValid)
+ return;
+
+ elog(DEBUG3, "cache_locale_time() executed; locale: \"%s\"", locale_time);
+
+ /* set user's value of time locale */
+ save_lc_time = setlocale(LC_TIME, NULL);
+ if (save_lc_time)
+ save_lc_time = pstrdup(save_lc_time);
+
+ setlocale(LC_TIME, locale_time);
+
+ timenow = time(NULL);
+ timeinfo = localtime(&timenow);
+
+ /* localized days */
+ for (i = 0; i < 7; i++)
+ {
+ timeinfo->tm_wday = i;
+ strftime(buf, MAX_L10N_DATA, "%a", timeinfo);
+ ptr = MemoryContextStrdup(TopMemoryContext, buf);
+ if (localized_abbrev_days[i])
+ pfree(localized_abbrev_days[i]);
+ localized_abbrev_days[i] = ptr;
+
+ strftime(buf, MAX_L10N_DATA, "%A", timeinfo);
+ ptr = MemoryContextStrdup(TopMemoryContext, buf);
+ if (localized_full_days[i])
+ pfree(localized_full_days[i]);
+ localized_full_days[i] = ptr;
+ }
+
+ /* localized months */
+ for (i = 0; i < 12; i++)
+ {
+ timeinfo->tm_mon = i;
+ timeinfo->tm_mday = 1; /* make sure we don't have invalid date */
+ strftime(buf, MAX_L10N_DATA, "%b", timeinfo);
+ ptr = MemoryContextStrdup(TopMemoryContext, buf);
+ if (localized_abbrev_months[i])
+ pfree(localized_abbrev_months[i]);
+ localized_abbrev_months[i] = ptr;
+
+ strftime(buf, MAX_L10N_DATA, "%B", timeinfo);
+ ptr = MemoryContextStrdup(TopMemoryContext, buf);
+ if (localized_full_months[i])
+ pfree(localized_full_months[i]);
+ localized_full_months[i] = ptr;
+ }
+
+ /* try to restore internal settings */
+ if (save_lc_time)
+ {
+ setlocale(LC_TIME, save_lc_time);
+ pfree(save_lc_time);
+ }
+
+ CurrentLCTimeValid = true;
+}