11/* -----------------------------------------------------------------------
22 * formatting.c
33 *
4- * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.84 2005/01/13 01:40:13 tgl Exp $
4+ * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.85 2005/03/25 16:08:40 tgl Exp $
55 *
66 *
77 * Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group
@@ -379,7 +379,8 @@ typedef struct
379379 cc ,
380380 q ,
381381 j ,
382- us ;
382+ us ,
383+ yysz ; /* is it YY or YYYY ? */
383384} TmFromChar ;
384385
385386#define ZERO_tmfc ( _X ) memset(_X, 0, sizeof(TmFromChar))
@@ -390,11 +391,11 @@ typedef struct
390391 */
391392#ifdef DEBUG_TO_FROM_CHAR
392393#define DEBUG_TMFC ( _X ) \
393- elog(DEBUG_elog_output, "TMFC:\nhh %d\nam %d\npm %d\nmi %d\nss %d\nssss %d\nd %d\ndd %d\nddd %d\nmm %d\nms: %d\nyear %d\nbc %d\niw %d\nww %d\nw %d\ncc %d\nq %d\nj %d\nus: %d", \
394+ elog(DEBUG_elog_output, "TMFC:\nhh %d\nam %d\npm %d\nmi %d\nss %d\nssss %d\nd %d\ndd %d\nddd %d\nmm %d\nms: %d\nyear %d\nbc %d\niw %d\nww %d\nw %d\ncc %d\nq %d\nj %d\nus: %d\nyysz: %d ", \
394395 (_X)->hh, (_X)->am, (_X)->pm, (_X)->mi, (_X)->ss, \
395396 (_X)->ssss, (_X)->d, (_X)->dd, (_X)->ddd, (_X)->mm, (_X)->ms, \
396397 (_X)->year, (_X)->bc, (_X)->iw, (_X)->ww, (_X)->w, \
397- (_X)->cc, (_X)->q, (_X)->j, (_X)->us);
398+ (_X)->cc, (_X)->q, (_X)->j, (_X)->us, (_X)->yysz );
398399#define DEBUG_TM ( _X ) \
399400 elog(DEBUG_elog_output, "TM:\nsec %d\nyear %d\nmin %d\nwday %d\nhour %d\nyday %d\nmday %d\nnisdst %d\nmon %d\n",\
400401 (_X)->tm_sec, (_X)->tm_year,\
@@ -2463,7 +2464,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
24632464
24642465 sscanf (inout , "%d,%03d" , & cc , & tmfc -> year );
24652466 tmfc -> year += (cc * 1000 );
2466-
2467+ tmfc -> yysz = 4 ;
24672468 return strdigits_len (inout ) + 3 + SKIP_THth (suf );
24682469 }
24692470 break ;
@@ -2497,11 +2498,13 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
24972498 if (S_FM (suf ) || is_next_separator (node ))
24982499 {
24992500 sscanf (inout , "%d" , & tmfc -> year );
2501+ tmfc -> yysz = 4 ;
25002502 return strdigits_len (inout ) - 1 + SKIP_THth (suf );
25012503 }
25022504 else
25032505 {
25042506 sscanf (inout , "%04d" , & tmfc -> year );
2507+ tmfc -> yysz = 4 ;
25052508 return 3 + SKIP_THth (suf );
25062509 }
25072510 }
@@ -2537,7 +2540,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
25372540 tmfc -> year += 1000 ;
25382541 else
25392542 tmfc -> year += 2000 ;
2540-
2543+ tmfc -> yysz = 3 ;
25412544 return 2 + SKIP_THth (suf );
25422545 }
25432546 break ;
@@ -2572,7 +2575,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
25722575 tmfc -> year += 2000 ;
25732576 else
25742577 tmfc -> year += 1900 ;
2575-
2578+ tmfc -> yysz = 2 ;
25762579 return 1 + SKIP_THth (suf );
25772580 }
25782581 break ;
@@ -2603,7 +2606,7 @@ dch_date(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
26032606 * 1-digit year: always +2000
26042607 */
26052608 tmfc -> year += 2000 ;
2606-
2609+ tmfc -> yysz = 1 ;
26072610 return 0 + SKIP_THth (suf );
26082611 }
26092612 break ;
@@ -3171,8 +3174,24 @@ do_to_timestamp(text *date_txt, text *fmt,
31713174 }
31723175
31733176 if (tmfc .year )
3174- tm -> tm_year = tmfc .year ;
3175-
3177+ {
3178+ if (tmfc .yysz == 2 && tmfc .cc )
3179+ {
3180+ /* CC and YY defined
3181+ * why -[2000|1900]? See dch_date() DCH_YY code.
3182+ */
3183+ tm -> tm_year = (tmfc .cc - 1 )* 100 + (tmfc .year >= 2000 ? tmfc .year - 2000 : tmfc .year - 1900 );
3184+ }
3185+ else if (tmfc .yysz == 1 && tmfc .cc )
3186+ {
3187+ /* CC and Y defined
3188+ */
3189+ tm -> tm_year = (tmfc .cc - 1 )* 100 + tmfc .year - 2000 ;
3190+ }
3191+ else
3192+ /* set year (and ignore CC if defined) */
3193+ tm -> tm_year = tmfc .year ;
3194+ }
31763195 if (tmfc .bc )
31773196 {
31783197 if (tm -> tm_year > 0 )
0 commit comments