Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1a908a0

Browse files
committed
Fix datetime input parsing to accept YYYY-MONTHNAME-DD and related syntaxes,
which had been unintentionally broken by recent changes to tighten up theDateStyle rules for all-numeric date input. Add documentation andregression tests for this, too.
1 parent9ad53b0 commit1a908a0

File tree

4 files changed

+928
-20
lines changed

4 files changed

+928
-20
lines changed

‎doc/src/sgml/datatype.sgml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.130 2003/11/06 22:21:47 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.131 2003/11/16 20:29:16 tgl Exp $
33
-->
44

55
<chapter id="datatype">
@@ -1464,7 +1464,7 @@ SELECT b, char_length(b) FROM test2;
14641464
</row>
14651465
<row>
14661466
<entry>1999-01-08</entry>
1467-
<entry>ISO 8601, January 8 in any mode
1467+
<entry>ISO 8601; January 8 in any mode
14681468
(recommended format)</entry>
14691469
</row>
14701470
<row>
@@ -1484,6 +1484,30 @@ SELECT b, char_length(b) FROM test2;
14841484
February 3, 2001 in <literal>YMD</> mode
14851485
</entry>
14861486
</row>
1487+
<row>
1488+
<entry>1999-Jan-08</entry>
1489+
<entry>January 8 in any mode</entry>
1490+
</row>
1491+
<row>
1492+
<entry>Jan-08-1999</entry>
1493+
<entry>January 8 in any mode</entry>
1494+
</row>
1495+
<row>
1496+
<entry>08-Jan-1999</entry>
1497+
<entry>January 8 in any mode</entry>
1498+
</row>
1499+
<row>
1500+
<entry>99-Jan-08</entry>
1501+
<entry>January 8 in <literal>YMD</> mode, else error</entry>
1502+
</row>
1503+
<row>
1504+
<entry>08-Jan-99</entry>
1505+
<entry>January 8, except error in <literal>YMD</> mode</entry>
1506+
</row>
1507+
<row>
1508+
<entry>Jan-08-99</entry>
1509+
<entry>January 8, except error in <literal>YMD</> mode</entry>
1510+
</row>
14871511
<row>
14881512
<entry>19990108</entry>
14891513
<entry>ISO 8601; January 8, 1999 in any mode</entry>
@@ -1625,7 +1649,7 @@ SELECT b, char_length(b) FROM test2;
16251649
</row>
16261650
<row>
16271651
<entry><literal>zulu</literal></entry>
1628-
<entry>Military abbreviation forGMT</entry>
1652+
<entry>Military abbreviation forUTC</entry>
16291653
</row>
16301654
<row>
16311655
<entry><literal>z</literal></entry>

‎src/backend/utils/adt/datetime.c

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.118 2003/09/25 06:58:03 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.119 2003/11/16 20:29:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -25,7 +25,7 @@
2525
#include"utils/guc.h"
2626

2727

28-
staticintDecodeNumber(intflen,char*field,
28+
staticintDecodeNumber(intflen,char*field,boolhaveTextMonth,
2929
intfmask,int*tmask,
3030
structtm*tm,fsec_t*fsec,int*is2digits);
3131
staticintDecodeNumberField(intlen,char*str,
@@ -924,7 +924,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
924924
intval;
925925
intdterr;
926926
intmer=HR24;
927-
inthaveTextMonth= FALSE;
927+
boolhaveTextMonth= FALSE;
928928
intis2digits= FALSE;
929929
intbc= FALSE;
930930

@@ -1281,7 +1281,8 @@ DecodeDateTime(char **field, int *ftype, int nf,
12811281
/* otherwise it is a single date/time field... */
12821282
else
12831283
{
1284-
dterr=DecodeNumber(flen,field[i],fmask,
1284+
dterr=DecodeNumber(flen,field[i],
1285+
haveTextMonth,fmask,
12851286
&tmask,tm,
12861287
fsec,&is2digits);
12871288
if (dterr)
@@ -2032,6 +2033,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
20322033
else
20332034
{
20342035
dterr=DecodeNumber(flen,field[i],
2036+
FALSE,
20352037
(fmask |DTK_DATE_M),
20362038
&tmask,tm,
20372039
fsec,&is2digits);
@@ -2229,6 +2231,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
22292231
inti,
22302232
len;
22312233
intdterr;
2234+
boolhaveTextMonth= FALSE;
22322235
intbc= FALSE;
22332236
intis2digits= FALSE;
22342237
inttype,
@@ -2283,6 +2286,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
22832286
{
22842287
caseMONTH:
22852288
tm->tm_mon=val;
2289+
haveTextMonth= TRUE;
22862290
break;
22872291

22882292
caseADBC:
@@ -2312,7 +2316,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
23122316
if ((len=strlen(field[i])) <=0)
23132317
returnDTERR_BAD_FORMAT;
23142318

2315-
dterr=DecodeNumber(len,field[i],fmask,
2319+
dterr=DecodeNumber(len,field[i],haveTextMonth,fmask,
23162320
&dmask,tm,
23172321
&fsec,&is2digits);
23182322
if (dterr)
@@ -2444,7 +2448,7 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec)
24442448
* Return 0 if okay, a DTERR code if not.
24452449
*/
24462450
staticint
2447-
DecodeNumber(intflen,char*str,intfmask,
2451+
DecodeNumber(intflen,char*str,boolhaveTextMonth,intfmask,
24482452
int*tmask,structtm*tm,fsec_t*fsec,int*is2digits)
24492453
{
24502454
intval;
@@ -2534,10 +2538,59 @@ DecodeNumber(int flen, char *str, int fmask,
25342538
tm->tm_mon=val;
25352539
break;
25362540

2541+
case (DTK_M(MONTH)):
2542+
if (haveTextMonth)
2543+
{
2544+
/*
2545+
* We are at the first numeric field of a date that included
2546+
* a textual month name. We want to support the variants
2547+
* MON-DD-YYYY, DD-MON-YYYY, and YYYY-MON-DD as unambiguous
2548+
* inputs. We will also accept MON-DD-YY or DD-MON-YY in
2549+
* either DMY or MDY modes, as well as YY-MON-DD in YMD mode.
2550+
*/
2551+
if (flen >=3||DateOrder==DATEORDER_YMD)
2552+
{
2553+
*tmask=DTK_M(YEAR);
2554+
tm->tm_year=val;
2555+
}
2556+
else
2557+
{
2558+
*tmask=DTK_M(DAY);
2559+
tm->tm_mday=val;
2560+
}
2561+
}
2562+
else
2563+
{
2564+
/* Must be at second field of MM-DD-YY */
2565+
*tmask=DTK_M(DAY);
2566+
tm->tm_mday=val;
2567+
}
2568+
break;
2569+
25372570
case (DTK_M(YEAR) |DTK_M(MONTH)):
2538-
/* Must be at third field of YY-MM-DD */
2539-
*tmask=DTK_M(DAY);
2540-
tm->tm_mday=val;
2571+
if (haveTextMonth)
2572+
{
2573+
/* Need to accept DD-MON-YYYY even in YMD mode */
2574+
if (flen >=3&&*is2digits)
2575+
{
2576+
/* Guess that first numeric field is day was wrong */
2577+
*tmask=DTK_M(DAY);/* YEAR is already set */
2578+
tm->tm_mday=tm->tm_year;
2579+
tm->tm_year=val;
2580+
*is2digits= FALSE;
2581+
}
2582+
else
2583+
{
2584+
*tmask=DTK_M(DAY);
2585+
tm->tm_mday=val;
2586+
}
2587+
}
2588+
else
2589+
{
2590+
/* Must be at third field of YY-MM-DD */
2591+
*tmask=DTK_M(DAY);
2592+
tm->tm_mday=val;
2593+
}
25412594
break;
25422595

25432596
case (DTK_M(DAY)):
@@ -2552,12 +2605,6 @@ DecodeNumber(int flen, char *str, int fmask,
25522605
tm->tm_year=val;
25532606
break;
25542607

2555-
case (DTK_M(MONTH)):
2556-
/* Must be at second field of MM-DD-YY */
2557-
*tmask=DTK_M(DAY);
2558-
tm->tm_mday=val;
2559-
break;
2560-
25612608
case (DTK_M(YEAR) |DTK_M(MONTH) |DTK_M(DAY)):
25622609
/* we have all the date, so it must be a time field */
25632610
dterr=DecodeNumberField(flen,str,fmask,
@@ -2574,10 +2621,10 @@ DecodeNumber(int flen, char *str, int fmask,
25742621

25752622
/*
25762623
* When processing a year field, mark it for adjustment if it's
2577-
*exactly two digits.
2624+
*only one or two digits.
25782625
*/
25792626
if (*tmask==DTK_M(YEAR))
2580-
*is2digits= (flen==2);
2627+
*is2digits= (flen<=2);
25812628

25822629
return0;
25832630
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp