diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 9aba12726481b96aca163c9cbfb0116547de9df7..dbf5d40ce91d79dd24c1d8c5584b7682dc05ec4f 100644
--- a/src/backend/utils/adt/Makefile
+++ b/src/backend/utils/adt/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for utils/adt
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.30 1999/12/28 13:40:48 wieck Exp $
+#    $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.31 2000/01/07 17:22:47 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -35,7 +35,7 @@ OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o chunk.o \
 	regexp.o regproc.o ruleutils.o selfuncs.o sets.o \
 	tid.o timestamp.o varchar.o varlena.o version.o \
 	network.o mac.o inet_net_ntop.o inet_net_pton.o \
-	ri_triggers.o pg_lzcompress.o
+	ri_triggers.o pg_lzcompress.o pg_locale.o
 
 all: SUBSYS.o
 
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
new file mode 100644
index 0000000000000000000000000000000000000000..7688a753dbc830eef42a76669a7b4b34c0a8e976
--- /dev/null
+++ b/src/backend/utils/adt/pg_locale.c
@@ -0,0 +1,128 @@
+
+/*------
+ * pg_locale.c
+ *
+ *	The PostgreSQL locale utils.
+ *
+ *	2000 Karel Zak - Zakkr
+ *
+ *------
+ */
+ 
+#include <stdio.h>
+ 
+#include "postgres.h"
+ 
+#ifdef USE_LOCALE
+
+#include <locale.h>
+#include "utils/pg_locale.h"
+
+/* #define DEBUG_LOCALE_UTILS  */
+
+
+/*------
+ * Return in PG_LocaleCategories current locale setting 
+ *------
+ */  
+PG_LocaleCategories *
+PGLC_current( PG_LocaleCategories *lc )
+{
+	lc->lang	= getenv("LANG");		
+		
+lc->lc_ctype	= setlocale(LC_CTYPE,	  NULL);
+lc->lc_numeric	= setlocale(LC_NUMERIC,	  NULL);
+lc->lc_time	= setlocale(LC_TIME,	  NULL);
+lc->lc_collate	= setlocale(LC_COLLATE,	  NULL);
+lc->lc_monetary	= setlocale(LC_MONETARY,  NULL);
+lc->lc_messages	= setlocale(LC_MESSAGES,  NULL);
+
+	return lc;
+}	
+
+
+#ifdef DEBUG_LOCALE_UTILS 
+
+/*------
+ * Print a PG_LocaleCategories struct as DEBUG
+ *------
+ */
+PG_LocaleCategories *
+PGLC_debug_lc( PG_LocaleCategories *lc )
+{
+	elog(DEBUG, "CURRENT LOCALE ENVIRONMENT:\n\nLANG:   \t%s\nLC_CTYPE:\t%s\nLC_NUMERIC:\t%s\nLC_TIME:\t%s\nLC_COLLATE:\t%s\nLC_MONETARY:\t%s\nLC_MESSAGES:\t%s\n",
+		lc->lang,	
+		lc->lc_ctype,	
+		lc->lc_numeric,	
+        	lc->lc_time,	
+        	lc->lc_collate,	
+        	lc->lc_monetary,	
+        	lc->lc_messages	
+	);
+
+	return lc;	
+}
+
+#endif
+
+/*------
+ * Set locales via a PG_LocaleCategories struct 
+ *------
+ */
+PG_LocaleCategories *
+PGLC_setlocale( PG_LocaleCategories *lc )
+{
+	if (!setlocale(LC_CTYPE,	 lc->lc_ctype	))
+		elog(NOTICE, "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored.", lc->lc_ctype); 
+			
+	if (!setlocale(LC_NUMERIC,	lc->lc_numeric	))
+		elog(NOTICE, "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored.", lc->lc_numeric);
+			
+        if (!setlocale(LC_TIME,	 	lc->lc_time	))
+        	elog(NOTICE, "pg_setlocale(): 'LC_TIME=%s' cannot be honored.", lc->lc_time);
+        
+        if (!setlocale(LC_COLLATE,	lc->lc_collate	))
+		elog(NOTICE, "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored.", lc->lc_collate);
+
+        if (!setlocale(LC_MONETARY,   	lc->lc_monetary	))
+  		elog(NOTICE, "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored.", lc->lc_monetary);
+  
+        if (!setlocale(LC_MESSAGES,   	lc->lc_messages	))
+		elog(NOTICE, "pg_setlocale(): 'LC_MESSAGE=%s' cannot be honored.", lc->lc_messages);
+
+	return lc;
+}
+
+/*------
+ * Return the POSIX lconv struct (contains number/money formatting information)
+ * with locale information for *all* categories.
+ * => Returned lconv is *independent* on current locale catogories setting - in 
+ * contrast to standard localeconv().
+ *
+ * ! libc prepare memory space for lconv itself and all returned strings in 
+ *   lconv are *static strings*.	      		  
+ *------
+ */
+struct lconv *
+PGLC_localeconv()
+{
+	PG_LocaleCategories	lc;
+	struct lconv		*lconv;
+
+	/* Save current locale setting to lc */
+	PGLC_current(&lc);	
+	
+	/* Set all locale category for current lang */
+	setlocale(LC_ALL, "");
+	
+	/* Get numeric formatting information */ 
+	lconv = localeconv();		
+	
+	/* Set previous original locale */
+	PGLC_setlocale(&lc);
+
+	return lconv;
+}
+
+
+#endif /* USE_LOCALE */
diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5aee46c9b334a050005de4be3ddc870e1ee0c2a
--- /dev/null
+++ b/src/include/utils/pg_locale.h
@@ -0,0 +1,46 @@
+
+/*------
+ * pg_locale.h
+ *
+ *	The PostgreSQL locale utils
+ *
+ *	2000 Karel Zak - Zakkr
+ *
+ *------
+ */ 
+ 
+ #ifndef _PG_LOCALE_
+ #define _PG_LOCALE_
+ 
+ #ifdef USE_LOCALE
+ 
+/*------
+ * POSIX locale categories and environment variable LANG
+ *------
+ */
+typedef struct PG_LocaleCategories {
+	char	*lang,
+		*lc_ctype,
+		*lc_numeric,
+		*lc_time,
+		*lc_collate,
+		*lc_monetary,
+		*lc_messages;
+} PG_LocaleCategories;
+
+
+extern PG_LocaleCategories *PGLC_current( PG_LocaleCategories *lc );
+extern PG_LocaleCategories *PGLC_setlocale( PG_LocaleCategories *lc );
+
+/*------
+ * Return the POSIX lconv struct (contains number/money formatting information)
+ * with locale information for *all* categories. Returned lconv is *independent* 
+ * on current locale catogories setting - in contrast to standard localeconv().
+ *------
+ */
+extern struct lconv *PGLC_localeconv();
+
+ 
+#endif /* USE_LOCALE */
+ 
+#endif /* _PG_LOCALE_ */