Skip to content

Commit 6e26c00

Browse files
committed
Fix to_date to behave reasonably when CC and YY fields are both used.
Karel Zak
1 parent c90578a commit 6e26c00

File tree

2 files changed

+41
-11
lines changed

2 files changed

+41
-11
lines changed

doc/src/sgml/func.sgml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.241 2005/03/14 18:31:19 momjian Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.242 2005/03/25 16:08:39 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -4470,6 +4470,17 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
44704470
</para>
44714471
</listitem>
44724472

4473+
<listitem>
4474+
<para>
4475+
In conversions from string to <type>timestamp</type> or
4476+
<type>date</type>, the <literal>CC</literal> field is ignored if there
4477+
is a <literal>YYY</literal>, <literal>YYYY</literal> or
4478+
<literal>Y,YYY</literal> field. If <literal>CC</literal> is used with
4479+
<literal>YY</literal> or <literal>Y</literal> then the year is computed
4480+
as <literal>(CC-1)*100+YY</literal>.
4481+
</para>
4482+
</listitem>
4483+
44734484
<listitem>
44744485
<para>
44754486
Millisecond (<literal>MS</literal>) and microsecond (<literal>US</literal>)

src/backend/utils/adt/formatting.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy