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

Commit6d5d673

Browse files
author
Thomas G. Lockhart
committed
Be more careful to check input string lengths as well as values
when deciding whether a field is a year field. Assume *anything* longer than 2 digits (if it isn't a special-case doy) is a valid year. This should fix the "Y1K" and "Y10K" problems pointed out by Massimo recently.Check usage of BC to require a positive-valued year; before just used it to flip the sign of the year without checking. This led to problems near year zero.Allow a 5 digit "concatenated date" of 2 digit year plus day of year.Do 2->4 digit year correction for 6 and 5 digit "concatenated dates". Somehow forgot this originally. Guess not many folks use it...
1 parentc715788 commit6d5d673

File tree

1 file changed

+59
-20
lines changed
  • src/backend/utils/adt

1 file changed

+59
-20
lines changed

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

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.60 1998/12/31 16:30:57 thomas Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.61 1999/01/10 17:20:54 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -2839,12 +2839,15 @@ DecodeDateTime(char **field, int *ftype, int nf,
28392839
caseDTK_NUMBER:
28402840
flen=strlen(field[i]);
28412841

2842-
if (flen>4)
2842+
/* long numeric string and either no date or no time read yet?
2843+
* then interpret as a concatenated date or time... */
2844+
if ((flen>4)&& !((fmask&DTK_DATE_M)&& (fmask&DTK_TIME_M)))
28432845
{
28442846
if (DecodeNumberField(flen,field[i],fmask,&tmask,tm,fsec)!=0)
28452847
return-1;
28462848

28472849
}
2850+
/* otherwise it is a single date/time field... */
28482851
else
28492852
{
28502853
if (DecodeNumber(flen,field[i],fmask,&tmask,tm,fsec)!=0)
@@ -3000,7 +3003,12 @@ DecodeDateTime(char **field, int *ftype, int nf,
30003003

30013004
/* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
30023005
if (bc)
3003-
tm->tm_year=-(tm->tm_year-1);
3006+
{
3007+
if (tm->tm_year>0)
3008+
tm->tm_year=-(tm->tm_year-1);
3009+
else
3010+
elog(ERROR,"Inconsistant use of year %04d and 'BC'",tm->tm_year);
3011+
}
30043012

30053013
if ((mer!=HR24)&& (tm->tm_hour>12))
30063014
return-1;
@@ -3375,8 +3383,23 @@ DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double
33753383
printf("DecodeNumber- %s is %d fmask=%08x tmask=%08x\n",str,val,fmask,*tmask);
33763384
#endif
33773385

3378-
/* enough digits to be unequivocal year? */
3379-
if (flen==4)
3386+
/* Special case day of year? */
3387+
if ((flen==3)&& (fmask&DTK_M(YEAR))
3388+
&& ((val >=1)&& (val <=366)))
3389+
{
3390+
*tmask= (DTK_M(DOY) |DTK_M(MONTH) |DTK_M(DAY));
3391+
tm->tm_yday=val;
3392+
j2date((date2j(tm->tm_year,1,1)+tm->tm_yday-1),
3393+
&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
3394+
3395+
}
3396+
/* Enough digits to be unequivocal year?
3397+
* Used to test for 4 digits or more,
3398+
* but we now test first for a three-digit doy
3399+
* so anything bigger than two digits had better be
3400+
* an explicit year. - thomas 1999-01-09
3401+
*/
3402+
elseif (flen>2)
33803403
{
33813404
#ifdefDATEDEBUG
33823405
printf("DecodeNumber- match %d (%s) as year\n",val,str);
@@ -3399,18 +3422,8 @@ DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double
33993422

34003423
tm->tm_year=val;
34013424

3402-
/* special case day of year? */
3403-
}
3404-
elseif ((flen==3)&& (fmask&DTK_M(YEAR))
3405-
&& ((val >=1)&& (val <=366)))
3406-
{
3407-
*tmask= (DTK_M(DOY) |DTK_M(MONTH) |DTK_M(DAY));
3408-
tm->tm_yday=val;
3409-
j2date((date2j(tm->tm_year,1,1)+tm->tm_yday-1),
3410-
&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
3411-
3412-
/* already have year? then could be month */
34133425
}
3426+
/* already have year? then could be month */
34143427
elseif ((fmask&DTK_M(YEAR))&& (!(fmask&DTK_M(MONTH)))
34153428
&& ((val >=1)&& (val <=12)))
34163429
{
@@ -3460,10 +3473,15 @@ DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double
34603473
#endif
34613474
*tmask=DTK_M(YEAR);
34623475
tm->tm_year=val;
3463-
if (tm->tm_year<70)
3464-
tm->tm_year+=2000;
3465-
elseif (tm->tm_year<100)
3466-
tm->tm_year+=1900;
3476+
3477+
/* adjust ONLY if exactly two digits... */
3478+
if (flen==2)
3479+
{
3480+
if (tm->tm_year<70)
3481+
tm->tm_year+=2000;
3482+
elseif (tm->tm_year<100)
3483+
tm->tm_year+=1900;
3484+
}
34673485

34683486
}
34693487
else
@@ -3527,9 +3545,30 @@ DecodeNumberField(int len, char *str, int fmask, int *tmask, struct tm * tm, dou
35273545
tm->tm_mon=atoi(str+2);
35283546
*(str+2)='\0';
35293547
tm->tm_year=atoi(str+0);
3548+
3549+
if (tm->tm_year<70)
3550+
tm->tm_year+=2000;
3551+
elseif (tm->tm_year<100)
3552+
tm->tm_year+=1900;
35303553
}
35313554

35323555
}
3556+
elseif ((len==5)&& !(fmask&DTK_DATE_M))
3557+
{
3558+
#ifdefDATEDEBUG
3559+
printf("DecodeNumberField- %s is 5 characters fmask=%08x tmask=%08x\n",str,fmask,*tmask);
3560+
#endif
3561+
*tmask=DTK_DATE_M;
3562+
tm->tm_mday=atoi(str+2);
3563+
*(str+2)='\0';
3564+
tm->tm_mon=1;
3565+
tm->tm_year=atoi(str+0);
3566+
3567+
if (tm->tm_year<70)
3568+
tm->tm_year+=2000;
3569+
elseif (tm->tm_year<100)
3570+
tm->tm_year+=1900;
3571+
}
35333572
elseif (strchr(str,'.')!=NULL)
35343573
{
35353574
#ifdefDATEDEBUG

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp