*** ./doc/src/sgml/func.sgml.orig 2005-12-25 18:38:45.000000000 -0200 --- ./doc/src/sgml/func.sgml 2005-12-25 18:55:10.000000000 -0200 *************** *** 4648,4653 **** --- 4648,4658 ---- FX Month DD Day + TM prefix + translation mode (print localized day and month names) + TMMonth + + SP suffix spell mode (not yet implemented) DDSP *************** *** 4670,4675 **** --- 4675,4686 ---- + TM does not include trailing blanks. + + + + + to_timestamp and to_date skip multiple blank spaces in the input string if the FX option is not used. FX must be specified as the first item *** ./src/backend/utils/adt/formatting.c.orig 2005-12-23 23:16:14.000000000 -0200 --- ./src/backend/utils/adt/formatting.c 2005-12-25 18:03:32.000000000 -0200 *************** *** 73,78 **** --- 73,79 ---- #include #include #include + #include #include "utils/builtins.h" #include "utils/date.h" *************** *** 82,87 **** --- 83,90 ---- #include "utils/numeric.h" #include "utils/pg_locale.h" + #define _(x) gettext((x)) + /* ---------- * Routines type * ---------- *************** *** 167,172 **** --- 170,179 ---- "August", "September", "October", "November", "December", NULL }; + static char *days_short[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL + }; + /* ---------- * AC / DC * ---------- *************** *** 466,471 **** --- 473,479 ---- #define DCH_S_TH 0x02 #define DCH_S_th 0x04 #define DCH_S_SP 0x08 + #define DCH_S_TM 0x10 /* ---------- * Suffix tests *************** *** 478,483 **** --- 486,492 ---- #define S_FM(_s) (((_s) & DCH_S_FM) ? 1 : 0) #define S_SP(_s) (((_s) & DCH_S_SP) ? 1 : 0) + #define S_TM(_s) (((_s) & DCH_S_TM) ? 1 : 0) /* ---------- * Suffixes definition for DATE-TIME TO/FROM CHAR *************** *** 486,491 **** --- 495,502 ---- static KeySuffix DCH_suff[] = { {"FM", 2, DCH_S_FM, SUFFTYPE_PREFIX}, {"fm", 2, DCH_S_FM, SUFFTYPE_PREFIX}, + {"TM", 2, DCH_S_TM, SUFFTYPE_PREFIX}, + {"tm", 2, DCH_S_TM, SUFFTYPE_PREFIX}, {"TH", 2, DCH_S_TH, SUFFTYPE_POSTFIX}, {"th", 2, DCH_S_th, SUFFTYPE_POSTFIX}, {"SP", 2, DCH_S_SP, SUFFTYPE_POSTFIX}, *************** *** 929,934 **** --- 940,949 ---- 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 *************** *** 1330,1336 **** * The input string is shorter than format picture, so it's good * time to break this loop... * ! * Note: this isn't relevant for TO_CHAR mode, beacuse it use * 'inout' allocated by format picture length. */ break; --- 1345,1351 ---- * The input string is shorter than format picture, so it's good * time to break this loop... * ! * Note: this isn't relevant for TO_CHAR mode, because it uses * 'inout' allocated by format picture length. */ break; *************** *** 2062,2068 **** tmfc = (TmFromChar *) data; /* ! * In the FROM-char is not difference between "January" or "JANUARY" or * "january", all is before search convert to "first-upper". This * convention is used for MONTH, MON, DAY, DY */ --- 2077,2083 ---- tmfc = (TmFromChar *) data; /* ! * In the FROM-char there is no difference between "January" or "JANUARY" or * "january", all is before search convert to "first-upper". This * convention is used for MONTH, MON, DAY, DY */ *************** *** 2166,2187 **** INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! strcpy(workbuff, months_full[tm->tm_mon - 1]); ! sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(workbuff)); return strlen(p_inout); case DCH_Month: INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]); return strlen(p_inout); case DCH_month: INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]); *inout = pg_tolower((unsigned char) *inout); return strlen(p_inout); --- 2181,2211 ---- INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! if (S_TM(suf)) ! 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); case DCH_Month: INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! if (S_TM(suf)) ! 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: INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! if (S_TM(suf)) ! 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); *************** *** 2189,2195 **** INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! strcpy(inout, months[tm->tm_mon - 1]); str_toupper(inout); return strlen(p_inout); --- 2213,2222 ---- INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! if (S_TM(suf)) ! strcpy(inout, localize_month(tm->tm_mon - 1)); ! else ! strcpy(inout, months[tm->tm_mon - 1]); str_toupper(inout); return strlen(p_inout); *************** *** 2197,2210 **** INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! strcpy(inout, months[tm->tm_mon - 1]); return strlen(p_inout); case DCH_mon: INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! strcpy(inout, months[tm->tm_mon - 1]); *inout = pg_tolower((unsigned char) *inout); return strlen(p_inout); --- 2224,2243 ---- INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! if (S_TM(suf)) ! strcpy(inout, localize_month(tm->tm_mon - 1)); ! else ! strcpy(inout, months[tm->tm_mon - 1]); return strlen(p_inout); case DCH_mon: INVALID_FOR_INTERVAL; if (!tm->tm_mon) return -1; ! if (S_TM(suf)) ! 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); *************** *** 2232,2268 **** break; case DCH_DAY: INVALID_FOR_INTERVAL; ! strcpy(workbuff, days[tm->tm_wday]); ! sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, str_toupper(workbuff)); return strlen(p_inout); case DCH_Day: INVALID_FOR_INTERVAL; ! sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]); return strlen(p_inout); case DCH_day: INVALID_FOR_INTERVAL; ! 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; ! strcpy(inout, days[tm->tm_wday]); str_toupper(inout); ! return 3; /* truncate */ case DCH_Dy: INVALID_FOR_INTERVAL; ! strcpy(inout, days[tm->tm_wday]); ! return 3; /* truncate */ case DCH_dy: INVALID_FOR_INTERVAL; ! strcpy(inout, days[tm->tm_wday]); *inout = pg_tolower((unsigned char) *inout); ! return 3; /* truncate */ case DCH_DDD: if (is_to_char) --- 2265,2319 ---- break; case DCH_DAY: INVALID_FOR_INTERVAL; ! if (S_TM(suf)) ! 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)) ! 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)) ! 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)) ! 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)) ! 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)) ! 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); case DCH_DDD: if (is_to_char) *************** *** 2802,2807 **** --- 2853,3020 ---- 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 ***************************************************************************/