New datestyle(s) - Mailing list pgsql-sql
From | Peter Koczan |
---|---|
Subject | New datestyle(s) |
Date | |
Msg-id | 4544e0330902161403m5ed2cdech26402a658ba26077@mail.gmail.com Whole thread Raw |
List | pgsql-sql |
Anyway, this is in response to a really old request of mine to easily and automatically get a datestyle for a different DBMS as part of an ongoing port process (http://archives.postgresql.org/pgsql-sql/2008-05/msg00048.php). I patched this a while ago and I finally got a chance to test it. Overall, it was pretty easy once I figured out how existing datestyles were coded (lots of grep'ing was involved). So, I figured I'd share what I did and also share the source patch in case anyone would either like a Sybase/SQL Server datestyle or a model on how to add your own custom datestyles. You need to edit the following files: src/backend/commands/variable.c - Add in your new datestyle to the list to allow it to be a valid option for "SET datestyle TO <x>" src/backend/utils/adt/datetime.c - Define your output format. A little hack-ish but pretty straightforward overall. src/include/miscadmin.h - Define your new datestyle. src/bin/psql/tab-complete.c - Not necessary to add it, but having it in the list of tab completions for datestyle is nice. I don't use the ecpg interface, so I didn't bother patching that. It seems like it would be analogous to what's been done already. Peter Index: src/backend/commands/variable.c =================================================================== RCS file: /s/postgresql-8.3.3/src/CVSROOT/postgresql-8.3.3/src/backend/commands/variable.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/backend/commands/variable.c 3 Sep 2008 18:30:21 -0000 1.1 +++ src/backend/commands/variable.c 3 Sep 2008 18:52:50 -0000 1.2 @@ -100,6 +100,13 @@ if (!have_order) newDateOrder = DATEORDER_DMY; } + else if (pg_strcasecmp(tok, "SYBASE") == 0) + { + if (have_style && newDateStyle != USE_SYBASE_DATES) + ok = false; /* conflicting styles */ + newDateStyle = USE_SYBASE_DATES; + have_style = true; + } else if (pg_strcasecmp(tok, "YMD") == 0) { if (have_order && newDateOrder != DATEORDER_YMD) @@ -200,6 +207,9 @@ case USE_GERMAN_DATES: strcpy(result, "German"); break; + case USE_SYBASE_DATES: + strcpy(result, "Sybase"); + break; default: strcpy(result, "Postgres"); break; Index: src/backend/utils/adt/datetime.c =================================================================== RCS file: /s/postgresql-8.3.3/src/CVSROOT/postgresql-8.3.3/src/backend/utils/adt/datetime.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/backend/utils/adt/datetime.c 3 Sep 2008 18:30:26 -0000 1.1 +++ src/backend/utils/adt/datetime.c 3 Sep 2008 18:53:29 -0000 1.2 @@ -3233,6 +3233,15 @@ sprintf(str + 5, ".%04d %s", -(tm->tm_year - 1), "BC"); break; + case USE_SYBASE_DATES: + /* Sybase date format */ + sprintf(str, "%s %2d", months[tm->tm_mon - 1], tm->tm_mday); + if (tm->tm_year > 0) + sprintf(str + 6, " %04d", tm->tm_year); + else + sprintf(str + 6, " %04d %s", -(tm->tm_year - 1), "BC"); + break; + case USE_POSTGRES_DATES: default: /* traditional date-only style for Postgres */ @@ -3302,6 +3311,8 @@EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, char *str){ int day; + bool meridian; + int temp_hour; /* * Why are we checking only the month field? Change this to an assert... @@ -3452,6 +3463,32 @@ sprintf(str + strlen(str), " BC"); break; + case USE_SYBASE_DATES: + /* Sybase date format */ + meridian = true; // true = AM, false = PM + temp_hour = tm->tm_hour; + + if (temp_hour < 12) + { + meridian = true; + if (temp_hour == 0) temp_hour = 12; + } + else + { + meridian = false; + if (temp_hour > 12) temp_hour -= 12; + } + + sprintf(str, "%s %2d %04d %2d:%02d%s", + months[tm->tm_mon - 1], tm->tm_mday, + (tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1), + temp_hour, tm->tm_min, + (meridian) ? "AM" : "PM"); + + if (tm->tm_year <= 0) + sprintf(str + strlen(str), " BC"); + break; + case USE_POSTGRES_DATES: default: /* Backward-compatible with traditional Postgres abstime dates*/ Index: src/include/miscadmin.h =================================================================== RCS file: /s/postgresql-8.3.3/src/CVSROOT/postgresql-8.3.3/src/include/miscadmin.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/include/miscadmin.h 3 Sep 2008 18:30:34 -0000 1.1 +++ src/include/miscadmin.h 3 Sep 2008 18:53:45 -0000 1.2 @@ -183,6 +183,7 @@#define USE_SQL_DATES 2#define USE_GERMAN_DATES 3#define USE_XSD_DATES 4 +#define USE_SYBASE_DATES 5 /* valid DateOrder values */#define DATEORDER_YMD 0 Index: src/bin/psql/tab-complete.c =================================================================== RCS file: /s/postgresql-8.3.3/src/CVSROOT/postgresql-8.3.3/src/bin/psql/tab-complete.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/bin/psql/tab-complete.c 3 Sep 2008 18:30:34 -0000 1.1 +++ src/bin/psql/tab-complete.c 3 Sep 2008 18:53:42 -0000 1.2 @@ -1888,7 +1888,7 @@ if (pg_strcasecmp(prev2_wd, "DateStyle") == 0) { static const char *constmy_list[] = - {"ISO", "SQL", "Postgres", "German", + {"ISO", "SQL", "Postgres", "German", "Sybase", "YMD", "DMY", "MDY", "US", "European","NonEuropean", "DEFAULT", NULL};