mirror of
https://github.com/postgres/postgres.git
synced 2025-06-08 22:02:03 +03:00
Fix to_date() and to_timestamp() to handle year masks of length < 4 so
they wrap toward year 2020, rather than the inconsistent behavior we had before.
This commit is contained in:
parent
8eacb25cbe
commit
029dfdf115
@ -5548,6 +5548,15 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If the year format specification is less than four digits, e.g.
|
||||||
|
<literal>YYY</>, and the supplied year is less than four digits,
|
||||||
|
the year will be adjusted to be nearest to the year 2020, e.g.
|
||||||
|
<literal>95</> becomes 1995.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The <literal>YYYY</literal> conversion from string to <type>timestamp</type> or
|
The <literal>YYYY</literal> conversion from string to <type>timestamp</type> or
|
||||||
|
@ -964,6 +964,7 @@ static void dump_node(FormatNode *node, int max);
|
|||||||
|
|
||||||
static char *get_th(char *num, int type);
|
static char *get_th(char *num, int type);
|
||||||
static char *str_numth(char *dest, char *num, int type);
|
static char *str_numth(char *dest, char *num, int type);
|
||||||
|
static int adjust_partial_year_to_2020(int year);
|
||||||
static int strspace_len(char *str);
|
static int strspace_len(char *str);
|
||||||
static int strdigits_len(char *str);
|
static int strdigits_len(char *str);
|
||||||
static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode);
|
static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode);
|
||||||
@ -1968,6 +1969,31 @@ is_next_separator(FormatNode *n)
|
|||||||
return TRUE; /* some non-digit input (separator) */
|
return TRUE; /* some non-digit input (separator) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
adjust_partial_year_to_2020(int year)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Adjust all dates toward 2020; this is effectively what happens
|
||||||
|
* when we assume '70' is 1970 and '69' is 2069.
|
||||||
|
*/
|
||||||
|
/* Force 0-69 into the 2000's */
|
||||||
|
if (year < 70)
|
||||||
|
return year + 2000;
|
||||||
|
/* Force 70-99 into the 1900's */
|
||||||
|
else if (year >= 70 && year < 100)
|
||||||
|
return year + 1900;
|
||||||
|
/* Force 100-519 into the 2000's */
|
||||||
|
else if (year >= 100 && year < 519)
|
||||||
|
return year + 2000;
|
||||||
|
/* Force 520-999 into the 1000's */
|
||||||
|
else if (year >= 520 && year < 1000)
|
||||||
|
return year + 1000;
|
||||||
|
else
|
||||||
|
return year;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
strspace_len(char *str)
|
strspace_len(char *str)
|
||||||
{
|
{
|
||||||
@ -2930,43 +2956,23 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
|
|||||||
break;
|
break;
|
||||||
case DCH_YYY:
|
case DCH_YYY:
|
||||||
case DCH_IYY:
|
case DCH_IYY:
|
||||||
from_char_parse_int(&out->year, &s, n);
|
if (from_char_parse_int(&out->year, &s, n) < 4)
|
||||||
|
out->year = adjust_partial_year_to_2020(out->year);
|
||||||
out->yysz = 3;
|
out->yysz = 3;
|
||||||
|
|
||||||
/*
|
|
||||||
* 3-digit year: '100' ... '999' = 1100 ... 1999 '000' ...
|
|
||||||
* '099' = 2000 ... 2099
|
|
||||||
*/
|
|
||||||
if (out->year >= 100)
|
|
||||||
out->year += 1000;
|
|
||||||
else
|
|
||||||
out->year += 2000;
|
|
||||||
s += SKIP_THth(n->suffix);
|
s += SKIP_THth(n->suffix);
|
||||||
break;
|
break;
|
||||||
case DCH_YY:
|
case DCH_YY:
|
||||||
case DCH_IY:
|
case DCH_IY:
|
||||||
from_char_parse_int(&out->year, &s, n);
|
if (from_char_parse_int(&out->year, &s, n) < 4)
|
||||||
|
out->year = adjust_partial_year_to_2020(out->year);
|
||||||
out->yysz = 2;
|
out->yysz = 2;
|
||||||
|
|
||||||
/*
|
|
||||||
* 2-digit year: '00' ... '69' = 2000 ... 2069 '70' ... '99'
|
|
||||||
* = 1970 ... 1999
|
|
||||||
*/
|
|
||||||
if (out->year < 70)
|
|
||||||
out->year += 2000;
|
|
||||||
else
|
|
||||||
out->year += 1900;
|
|
||||||
s += SKIP_THth(n->suffix);
|
s += SKIP_THth(n->suffix);
|
||||||
break;
|
break;
|
||||||
case DCH_Y:
|
case DCH_Y:
|
||||||
case DCH_I:
|
case DCH_I:
|
||||||
from_char_parse_int(&out->year, &s, n);
|
if (from_char_parse_int(&out->year, &s, n) < 4)
|
||||||
|
out->year = adjust_partial_year_to_2020(out->year);
|
||||||
out->yysz = 1;
|
out->yysz = 1;
|
||||||
|
|
||||||
/*
|
|
||||||
* 1-digit year: always +2000
|
|
||||||
*/
|
|
||||||
out->year += 2000;
|
|
||||||
s += SKIP_THth(n->suffix);
|
s += SKIP_THth(n->suffix);
|
||||||
break;
|
break;
|
||||||
case DCH_RM:
|
case DCH_RM:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user