Here's a patch for initdb detecting the date order of the lc_time locale 
and initializing the datestyle parameter of the new cluster 
accordingly.

This relies on feeding an umambiguous date through strftime("%x") and 
checking in which order things come out.  (This was suggested to me by 
Martin Pitt a while ago.)  I've tested this with a number of locales 
and it seems to work.  Does anyone see a problem with this?

(Documentation and perhaps an initdb progress notification line is of 
course still missing.)

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/
diff -ur ../../../../cvs-pgsql/src/bin/initdb/initdb.c ./initdb.c
--- ../../../../cvs-pgsql/src/bin/initdb/initdb.c	2005-12-03 22:30:51.000000000 +0100
+++ ./initdb.c	2005-12-09 02:28:41.000000000 +0100
@@ -57,11 +57,13 @@
 #ifdef HAVE_LANGINFO_H
 #include <langinfo.h>
 #endif
+#include <time.h>
 
 #include "libpq/pqsignal.h"
 #include "mb/pg_wchar.h"
 #include "getaddrinfo.h"
 #include "getopt_long.h"
+#include "miscadmin.h"
 
 #ifndef HAVE_INT_OPTRESET
 int			optreset;
@@ -186,6 +188,7 @@
 static void trapsig(int signum);
 static void check_ok(void);
 static char *escape_quotes(const char *src);
+static int	locale_date_order(const char *locale);
 static bool chklocale(const char *locale);
 static void setlocales(void);
 static void usage(const char *progname);
@@ -1195,6 +1198,20 @@
 	snprintf(repltok, sizeof(repltok), "lc_time = '%s'", lc_time);
 	conflines = replace_token(conflines, "#lc_time = 'C'", repltok);
 
+	switch (locale_date_order(lc_time)) {
+		case DATEORDER_YMD:
+			strcpy(repltok, "datestyle = 'iso, ymd'");
+			break;
+		case DATEORDER_DMY:
+			strcpy(repltok, "datestyle = 'iso, dmy'");
+			break;
+		case DATEORDER_MDY:
+		default:
+			strcpy(repltok, "datestyle = 'iso, mdy'");
+			break;
+	}
+	conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok);
+
 	snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
 
 	writefile(path, conflines);
@@ -2053,6 +2070,51 @@
 }
 
 /*
+ * Determine likely date order from locale
+ */
+static int
+locale_date_order(const char *locale)
+{
+	struct tm	testtime;
+	char		buf[128];
+	char	   *posD;
+	char	   *posM;
+	char	   *posY;
+	char	   *save;
+	size_t		res;
+
+	save = setlocale(LC_TIME, NULL);
+	if (!save)
+		return DATEORDER_MDY;
+	save = xstrdup(save);
+
+	setlocale(LC_TIME, locale);
+
+	memset(&testtime, 0, sizeof(testtime));
+	testtime.tm_mday = 22;
+	testtime.tm_mon = 10;		/* November, should come out as "11" */
+	testtime.tm_year = 133;		/* 2033 */
+
+	res = strftime(buf, sizeof(buf), "%x", &testtime);
+
+	setlocale(LC_TIME, save);
+	free(save);
+
+	if (res == 0)
+		return DATEORDER_MDY;
+
+	posM = strstr(buf, "11");
+	posD = strstr(buf, "22");
+	posY = strstr(buf, "33");
+
+	if (posY < posD && posY < posM)
+		return DATEORDER_YMD;
+	if (posD < posM)
+		return DATEORDER_DMY;
+	return DATEORDER_MDY;
+}
+
+/*
  * check if given string is a valid locale specifier
  */
 static bool
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

               http://archives.postgresql.org

Reply via email to