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 */
3131#endif
3232#include "utils/builtins.h"
3333
34+
3435static int DecodeDate (char * str ,int fmask ,int * tmask ,struct tm * tm );
3536static int DecodeNumber (int flen ,char * field ,
36- int fmask ,int * tmask ,struct tm * tm ,double * fsec );
37+ int fmask ,int * tmask ,struct tm * tm ,double * fsec , int * is2digits );
3738static int DecodeNumberField (int len ,char * str ,
38- int fmask ,int * tmask ,struct tm * tm ,double * fsec );
39+ int fmask ,int * tmask ,struct tm * tm ,double * fsec , int * is2digits );
3940static int DecodeSpecial (int field ,char * lowtoken ,int * val );
4041static int DecodeTime (char * str ,int fmask ,int * tmask ,
4142struct tm * tm ,double * fsec );
@@ -50,12 +51,20 @@ static double time2t(const int hour, const int min, const double sec);
5051static int timespan2tm (TimeSpan span ,struct tm * tm ,float8 * fsec );
5152static int tm2timespan (struct tm * tm ,double fsec ,TimeSpan * span );
5253
54+
5355#define USE_DATE_CACHE 1
5456#define ROUND_ALL 0
5557
58+ #if 0
5659#define isleap (y ) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
5760
5861int mdays []= {31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 ,0 };
62+ #endif
63+
64+ int day_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
6069char * 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+ #if 0
876886if (tm -> tm_mday > mdays [tm -> tm_mon - 1 ])
877887{
878888if ((tm -> tm_mon == 2 )&& isleap (tm -> tm_year ))
879889tm -> tm_mday = (mdays [tm -> tm_mon - 1 ]+ 1 );
880890else
881891tm -> 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#ifdef DATEDEBUG
885898printf ("datetime_pl_span- date becomes %04d-%02d-%02d %02d:%02d:%02d\n" ,
@@ -1184,16 +1197,22 @@ datetime_age(DateTime *datetime1, DateTime *datetime2)
11841197{
11851198if (dt1 < dt2 )
11861199{
1200+ #if 0
11871201tm -> tm_mday += mdays [tm1 -> tm_mon - 1 ];
11881202if (isleap (tm1 -> tm_year )&& (tm1 -> tm_mon == 2 ))
11891203tm -> tm_mday ++ ;
1204+ #endif
1205+ tm -> tm_mday += day_tab [isleap (tm1 -> tm_year )][tm1 -> tm_mon - 1 ];
11901206tm -> tm_mon -- ;
11911207}
11921208else
11931209{
1210+ #if 0
11941211tm -> tm_mday += mdays [tm2 -> tm_mon - 1 ];
11951212if (isleap (tm2 -> tm_year )&& (tm2 -> tm_mon == 2 ))
11961213tm -> tm_mday ++ ;
1214+ #endif
1215+ tm -> tm_mday += day_tab [isleap (tm2 -> tm_year )][tm2 -> tm_mon - 1 ];
11971216tm -> 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+ #if 0
2306+ XXX moved to dt .h - thomas 1999 - 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#define IS_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
22982320int
22992321date2j (int y ,int m ,int d )
@@ -2792,6 +2814,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
27922814int flen ,
27932815val ;
27942816int mer = HR24 ;
2817+ int is2digits = FALSE;
27952818int bc = 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... */
28442867if ((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 )
28472870return -1 ;
28482871
28492872}
28502873/* otherwise it is a single date/time field... */
28512874else
28522875{
2853- if (DecodeNumber (flen ,field [i ],fmask ,& tmask ,tm ,fsec )!= 0 )
2876+ if (DecodeNumber (flen ,field [i ],fmask ,& tmask ,tm ,fsec , & is2digits )!= 0 )
28542877return -1 ;
28552878}
28562879break ;
@@ -3009,6 +3032,13 @@ DecodeDateTime(char **field, int *ftype, int nf,
30093032else
30103033elog (ERROR ,"Inconsistant use of year %04d and 'BC'" ,tm -> tm_year );
30113034}
3035+ else if (is2digits )
3036+ {
3037+ if (tm -> tm_year < 70 )
3038+ tm -> tm_year += 2000 ;
3039+ else if (tm -> tm_year < 100 )
3040+ tm -> tm_year += 1900 ;
3041+ }
30123042
30133043if ((mer != HR24 )&& (tm -> tm_hour > 12 ))
30143044return -1 ;
@@ -3083,6 +3113,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
30833113int i ;
30843114int flen ,
30853115val ;
3116+ int is2digits = FALSE;
30863117int mer = HR24 ;
30873118
30883119* dtype = DTK_TIME ;
@@ -3110,7 +3141,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
31103141case DTK_NUMBER :
31113142flen = 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 )
31143145return -1 ;
31153146break ;
31163147
@@ -3209,6 +3240,8 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32093240int nf = 0 ;
32103241int i ,
32113242len ;
3243+ int bc = FALSE;
3244+ int is2digits = FALSE;
32123245int type ,
32133246val ,
32143247dmask = 0 ;
@@ -3238,9 +3271,11 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32383271nf ++ ;
32393272}
32403273
3274+ #if 0
32413275/* don't allow too many fields */
32423276if (nf > 3 )
32433277return -1 ;
3278+ #endif
32443279
32453280* tmask = 0 ;
32463281
@@ -3263,6 +3298,10 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm * tm)
32633298tm -> tm_mon = val ;
32643299break ;
32653300
3301+ case ADBC :
3302+ bc = (val == BC );
3303+ break ;
3304+
32663305default :
32673306#ifdef DATEDEBUG
32683307printf ("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)
32893328if ((len = strlen (field [i ])) <=0 )
32903329return -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 )
32933332return -1 ;
32943333
32953334if (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+ else if (is2digits )
3353+ {
3354+ if (tm -> tm_year < 70 )
3355+ tm -> tm_year += 2000 ;
3356+ else if (tm -> tm_year < 100 )
3357+ tm -> tm_year += 1900 ;
3358+ }
3359+
33023360return 0 ;
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 */
33643422static int
3365- DecodeNumber (int flen ,char * str ,int fmask ,int * tmask ,struct tm * tm ,double * fsec )
3423+ DecodeNumber (int flen ,char * str ,int fmask ,
3424+ int * tmask ,struct tm * tm ,double * fsec ,int * is2digits )
33663425{
33673426int val ;
33683427char * cp ;
@@ -3475,13 +3534,16 @@ DecodeNumber(int flen, char *str, int fmask, int *tmask, struct tm * tm, double
34753534tm -> tm_year = val ;
34763535
34773536/* adjust ONLY if exactly two digits... */
3537+ #if 0
34783538if (flen == 2 )
34793539{
34803540if (tm -> tm_year < 70 )
34813541tm -> tm_year += 2000 ;
34823542else if (tm -> tm_year < 100 )
34833543tm -> tm_year += 1900 ;
34843544}
3545+ #endif
3546+ * is2digits = (flen == 2 );
34853547
34863548}
34873549else
@@ -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 */
34973559static int
3498- DecodeNumberField (int len ,char * str ,int fmask ,int * tmask ,struct tm * tm ,double * fsec )
3560+ DecodeNumberField (int len ,char * str ,int fmask ,
3561+ int * tmask ,struct tm * tm ,double * fsec ,int * is2digits )
34993562{
35003563char * cp ;
35013564
@@ -3546,10 +3609,13 @@ DecodeNumberField(int len, char *str, int fmask, int *tmask, struct tm * tm, dou
35463609* (str + 2 )= '\0' ;
35473610tm -> tm_year = atoi (str + 0 );
35483611
3612+ #if 0
35493613if (tm -> tm_year < 70 )
35503614tm -> tm_year += 2000 ;
35513615else if (tm -> tm_year < 100 )
35523616tm -> 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
35643630tm -> tm_mon = 1 ;
35653631tm -> tm_year = atoi (str + 0 );
35663632
3633+ #if 0
35673634if (tm -> tm_year < 70 )
35683635tm -> tm_year += 2000 ;
35693636else if (tm -> tm_year < 100 )
35703637tm -> tm_year += 1900 ;
3638+ #endif
3639+ * is2digits = TRUE;
35713640}
35723641else if (strchr (str ,'.' )!= NULL )
35733642{