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

Commit1ace93c

Browse files
author
Thomas G. Lockhart
committed
Fix "Y-2K" problem with two-digit BC dates being corrected by two millenia.
They are not corrected now.Allow the date type to accept BC dates.Share more date/time validation declarations through dt.h.
1 parent791822e commit1ace93c

File tree

2 files changed

+88
-16
lines changed

2 files changed

+88
-16
lines changed

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

Lines changed: 5 additions & 2 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/datetime.c,v 1.26 1998/12/31 16:30:56 thomas Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.27 1999/01/20 16:29:39 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -27,12 +27,13 @@
2727

2828
staticintdate2tm(DateADTdateVal,int*tzp,structtm*tm,double*fsec,char**tzn);
2929

30-
30+
#if0
3131
staticintday_tab[2][12]= {
3232
{31,28,31,30,31,30,31,31,30,31,30,31},
3333
{31,29,31,30,31,30,31,31,30,31,30,31}};
3434

3535
#defineisleap(y) (((y % 4) == 0 && (y % 100) != 0) || (y % 400) == 0)
36+
#endif
3637

3738
#defineUTIME_MINYEAR (1901)
3839
#defineUTIME_MINMONTH (12)
@@ -99,10 +100,12 @@ date_in(char *str)
99100
elog(ERROR,"Unrecognized date external representation %s",str);
100101
}
101102

103+
#if0
102104
if (tm->tm_year<0||tm->tm_year>32767)
103105
elog(ERROR,"date_in: year must be limited to values 0 through 32767 in '%s'",str);
104106
if (tm->tm_mon<1||tm->tm_mon>12)
105107
elog(ERROR,"date_in: month must be limited to values 1 through 12 in '%s'",str);
108+
#endif
106109
if (tm->tm_mday<1||tm->tm_mday>day_tab[isleap(tm->tm_year)][tm->tm_mon-1])
107110
elog(ERROR,"date_in: day must be limited to values 1 through %d in '%s'",
108111
day_tab[isleap(tm->tm_year)][tm->tm_mon-1],str);

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

Lines changed: 83 additions & 14 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.61 1999/01/10 17:20:54 thomas Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.62 1999/01/20 16:29:39 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -31,11 +31,12 @@
3131
#endif
3232
#include"utils/builtins.h"
3333

34+
3435
staticintDecodeDate(char*str,intfmask,int*tmask,structtm*tm);
3536
staticintDecodeNumber(intflen,char*field,
36-
intfmask,int*tmask,structtm*tm,double*fsec);
37+
intfmask,int*tmask,structtm*tm,double*fsec,int*is2digits);
3738
staticintDecodeNumberField(intlen,char*str,
38-
intfmask,int*tmask,structtm*tm,double*fsec);
39+
intfmask,int*tmask,structtm*tm,double*fsec,int*is2digits);
3940
staticintDecodeSpecial(intfield,char*lowtoken,int*val);
4041
staticintDecodeTime(char*str,intfmask,int*tmask,
4142
structtm*tm,double*fsec);
@@ -50,12 +51,20 @@ static double time2t(const int hour, const int min, const double sec);
5051
staticinttimespan2tm(TimeSpanspan,structtm*tm,float8*fsec);
5152
staticinttm2timespan(structtm*tm,doublefsec,TimeSpan*span);
5253

54+
5355
#defineUSE_DATE_CACHE 1
5456
#defineROUND_ALL 0
5557

58+
#if0
5659
#defineisleap(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
5760

5861
intmdays[]= {31,28,31,30,31,30,31,31,30,31,30,31,0};
62+
#endif
63+
64+
intday_tab[2][13]= {
65+
{31,28,31,30,31,30,31,31,30,31,30,31,0},
66+
{31,29,31,30,31,30,31,31,30,31,30,31,0}};
67+
5968

6069
char*months[]= {"Jan","Feb","Mar","Apr","May","Jun",
6170
"Jul","Aug","Sep","Oct","Nov","Dec",NULL};
@@ -873,13 +882,17 @@ datetime_pl_span(DateTime *datetime, TimeSpan *span)
873882
}
874883

875884
/* adjust for end of month boundary problems... */
885+
#if0
876886
if (tm->tm_mday>mdays[tm->tm_mon-1])
877887
{
878888
if ((tm->tm_mon==2)&&isleap(tm->tm_year))
879889
tm->tm_mday= (mdays[tm->tm_mon-1]+1);
880890
else
881891
tm->tm_mday=mdays[tm->tm_mon-1];
882892
}
893+
#endif
894+
if (tm->tm_mday>day_tab[isleap(tm->tm_year)][tm->tm_mon-1])
895+
tm->tm_mday= (day_tab[isleap(tm->tm_year)][tm->tm_mon-1]);
883896

884897
#ifdefDATEDEBUG
885898
printf("datetime_pl_span- date becomes %04d-%02d-%02d %02d:%02d:%02d\n",
@@ -1184,16 +1197,22 @@ datetime_age(DateTime *datetime1, DateTime *datetime2)
11841197
{
11851198
if (dt1<dt2)
11861199
{
1200+
#if0
11871201
tm->tm_mday+=mdays[tm1->tm_mon-1];
11881202
if (isleap(tm1->tm_year)&& (tm1->tm_mon==2))
11891203
tm->tm_mday++;
1204+
#endif
1205+
tm->tm_mday+=day_tab[isleap(tm1->tm_year)][tm1->tm_mon-1];
11901206
tm->tm_mon--;
11911207
}
11921208
else
11931209
{
1210+
#if0
11941211
tm->tm_mday+=mdays[tm2->tm_mon-1];
11951212
if (isleap(tm2->tm_year)&& (tm2->tm_mon==2))
11961213
tm->tm_mday++;
1214+
#endif
1215+
tm->tm_mday+=day_tab[isleap(tm2->tm_year)][tm2->tm_mon-1];
11971216
tm->tm_mon--;
11981217
}
11991218
}
@@ -2036,7 +2055,7 @@ static datetkn datetktbl[] = {
20362055
{"adt",DTZ,NEG(18)},/* Atlantic Daylight Time */
20372056
{"aesst",DTZ,66},/* E. Australia */
20382057
{"aest",TZ,60},/* Australia Eastern Std Time */
2039-
{"ahst",TZ,60},/* Alaska-Hawaii Std Time */
2058+
{"ahst",TZ,NEG(60)},/* Alaska-Hawaii Std Time */
20402059
{"allballs",RESERV,DTK_ZULU},/* 00:00:00 */
20412060
{"am",AMPM,AM},
20422061
{"apr",MONTH,4},
@@ -2087,12 +2106,12 @@ static datetkn datetktbl[] = {
20872106
{"hmt",DTZ,18},/* Hellas ? ? */
20882107
{"hst",TZ,NEG(60)},/* Hawaii Std Time */
20892108
{"idle",TZ,72},/* Intl. Date Line, East */
2090-
{"idlw",TZ,NEG(72)},/* Intl. Date Line,,est */
2109+
{"idlw",TZ,NEG(72)},/* Intl. Date Line, West */
20912110
{LATE,RESERV,DTK_LATE},/* "infinity" reserved for "late time" */
2092-
{INVALID,RESERV,DTK_INVALID},/* "invalid" reserved for invalid
2093-
* time */
2111+
{INVALID,RESERV,DTK_INVALID},
2112+
/* "invalid" reserved for invalid time */
20942113
{"ist",TZ,12},/* Israel */
2095-
{"it",TZ,22},/* Iran Time */
2114+
{"it",TZ,21},/* Iran Time */
20962115
{"jan",MONTH,1},
20972116
{"january",MONTH,1},
20982117
{"jst",TZ,54},/* Japan Std Time,USSR Zone 8 */
@@ -2283,6 +2302,8 @@ datetkn *deltacache[MAXDATEFIELDS] = {NULL};
22832302
* These routines will be used by other date/time packages - tgl 97/02/25
22842303
*/
22852304

2305+
#if0
2306+
XXXmovedtodt.h-thomas1999-01-15
22862307
/* Set the minimum year to one greater than the year of the first valid day
22872308
*to avoid having to check year and day both. - tgl 97/05/08
22882309
*/
@@ -2294,6 +2315,7 @@ datetkn *deltacache[MAXDATEFIELDS] = {NULL};
22942315
#defineIS_VALID_JULIAN(y,m,d) ((y > JULIAN_MINYEAR) \
22952316
|| ((y == JULIAN_MINYEAR) && ((m > JULIAN_MINMONTH) \
22962317
|| ((m == JULIAN_MINMONTH) && (d >= JULIAN_MINDAY)))))
2318+
#endif
22972319

22982320
int
22992321
date2j(inty,intm,intd)
@@ -2792,6 +2814,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
27922814
intflen,
27932815
val;
27942816
intmer=HR24;
2817+
intis2digits= FALSE;
27952818
intbc= FALSE;
27962819

27972820
*dtype=DTK_DATE;
@@ -2843,14 +2866,14 @@ DecodeDateTime(char **field, int *ftype, int nf,
28432866
* then interpret as a concatenated date or time... */
28442867
if ((flen>4)&& !((fmask&DTK_DATE_M)&& (fmask&DTK_TIME_M)))
28452868
{
2846-
if (DecodeNumberField(flen,field[i],fmask,&tmask,tm,fsec)!=0)
2869+
if (DecodeNumberField(flen,field[i],fmask,&tmask,tm,fsec,&is2digits)!=0)
28472870
return-1;
28482871

28492872
}
28502873
/* otherwise it is a single date/time field... */
28512874
else
28522875
{
2853-
if (DecodeNumber(flen,field[i],fmask,&tmask,tm,fsec)!=0)
2876+
if (DecodeNumber(flen,field[i],fmask,&tmask,tm,fsec,&is2digits)!=0)
28542877
return-1;
28552878
}
28562879
break;
@@ -3009,6 +3032,13 @@ DecodeDateTime(char **field, int *ftype, int nf,
30093032
else
30103033
elog(ERROR,"Inconsistant use of year %04d and 'BC'",tm->tm_year);
30113034
}
3035+
elseif (is2digits)
3036+
{
3037+
if (tm->tm_year<70)
3038+
tm->tm_year+=2000;
3039+
elseif (tm->tm_year<100)
3040+
tm->tm_year+=1900;
3041+
}
30123042

30133043
if ((mer!=HR24)&& (tm->tm_hour>12))
30143044
return-1;
@@ -3083,6 +3113,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
30833113
inti;
30843114
intflen,
30853115
val;
3116+
intis2digits= FALSE;
30863117
intmer=HR24;
30873118

30883119
*dtype=DTK_TIME;
@@ -3110,7 +3141,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
31103141
caseDTK_NUMBER:
31113142
flen=strlen(field[i]);
31123143

3113-
if (DecodeNumberField(flen,field[i],fmask,&tmask,tm,fsec)!=0)
3144+
if (DecodeNumberField(flen,field[i],fmask,&tmask,tm,fsec,&is2digits)!=0)
31143145
return-1;
31153146
break;
31163147

@@ -3209,6 +3240,8 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32093240
intnf=0;
32103241
inti,
32113242
len;
3243+
intbc= FALSE;
3244+
intis2digits= FALSE;
32123245
inttype,
32133246
val,
32143247
dmask=0;
@@ -3238,9 +3271,11 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32383271
nf++;
32393272
}
32403273

3274+
#if0
32413275
/* don't allow too many fields */
32423276
if (nf>3)
32433277
return-1;
3278+
#endif
32443279

32453280
*tmask=0;
32463281

@@ -3263,6 +3298,10 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32633298
tm->tm_mon=val;
32643299
break;
32653300

3301+
caseADBC:
3302+
bc= (val==BC);
3303+
break;
3304+
32663305
default:
32673306
#ifdefDATEDEBUG
32683307
printf("DecodeDate- illegal field %s value is %d\n",field[i],val);
@@ -3289,7 +3328,7 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32893328
if ((len=strlen(field[i])) <=0)
32903329
return-1;
32913330

3292-
if (DecodeNumber(len,field[i],fmask,&dmask,tm,&fsec)!=0)
3331+
if (DecodeNumber(len,field[i],fmask,&dmask,tm,&fsec,&is2digits)!=0)
32933332
return-1;
32943333

32953334
if (fmask&dmask)
@@ -3299,6 +3338,25 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32993338
*tmask |=dmask;
33003339
}
33013340

3341+
if ((fmask& ~(DTK_M(DOY) |DTK_M(TZ)))!=DTK_DATE_M)
3342+
return-1;
3343+
3344+
/* there is no year zero in AD/BC notation; i.e. "1 BC" == year 0 */
3345+
if (bc)
3346+
{
3347+
if (tm->tm_year>0)
3348+
tm->tm_year=-(tm->tm_year-1);
3349+
else
3350+
elog(ERROR,"Inconsistant use of year %04d and 'BC'",tm->tm_year);
3351+
}
3352+
elseif (is2digits)
3353+
{
3354+
if (tm->tm_year<70)
3355+
tm->tm_year+=2000;
3356+
elseif (tm->tm_year<100)
3357+
tm->tm_year+=1900;
3358+
}
3359+
33023360
return0;
33033361
}/* DecodeDate() */
33043362

@@ -3362,7 +3420,8 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, double *fsec)
33623420
* Interpret numeric field as a date value in context.
33633421
*/
33643422
staticint
3365-
DecodeNumber(intflen,char*str,intfmask,int*tmask,structtm*tm,double*fsec)
3423+
DecodeNumber(intflen,char*str,intfmask,
3424+
int*tmask,structtm*tm,double*fsec,int*is2digits)
33663425
{
33673426
intval;
33683427
char*cp;
@@ -3475,13 +3534,16 @@ DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double
34753534
tm->tm_year=val;
34763535

34773536
/* adjust ONLY if exactly two digits... */
3537+
#if0
34783538
if (flen==2)
34793539
{
34803540
if (tm->tm_year<70)
34813541
tm->tm_year+=2000;
34823542
elseif (tm->tm_year<100)
34833543
tm->tm_year+=1900;
34843544
}
3545+
#endif
3546+
*is2digits= (flen==2);
34853547

34863548
}
34873549
else
@@ -3495,7 +3557,8 @@ DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double
34953557
* Interpret numeric string as a concatenated date field.
34963558
*/
34973559
staticint
3498-
DecodeNumberField(intlen,char*str,intfmask,int*tmask,structtm*tm,double*fsec)
3560+
DecodeNumberField(intlen,char*str,intfmask,
3561+
int*tmask,structtm*tm,double*fsec,int*is2digits)
34993562
{
35003563
char*cp;
35013564

@@ -3546,10 +3609,13 @@ DecodeNumberField(int len, char *str, int fmask, int *tmask, struct tm * tm, dou
35463609
*(str+2)='\0';
35473610
tm->tm_year=atoi(str+0);
35483611

3612+
#if0
35493613
if (tm->tm_year<70)
35503614
tm->tm_year+=2000;
35513615
elseif (tm->tm_year<100)
35523616
tm->tm_year+=1900;
3617+
#endif
3618+
*is2digits= TRUE;
35533619
}
35543620

35553621
}
@@ -3564,10 +3630,13 @@ DecodeNumberField(int len, char *str, int fmask, int *tmask, struct tm * tm, dou
35643630
tm->tm_mon=1;
35653631
tm->tm_year=atoi(str+0);
35663632

3633+
#if0
35673634
if (tm->tm_year<70)
35683635
tm->tm_year+=2000;
35693636
elseif (tm->tm_year<100)
35703637
tm->tm_year+=1900;
3638+
#endif
3639+
*is2digits= TRUE;
35713640
}
35723641
elseif (strchr(str,'.')!=NULL)
35733642
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp