77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.43 1997/10/25 05:18:17 thomas Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.44 1997/11/17 16:23:33 thomas Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -1803,6 +1803,14 @@ datetime_part(text *units, DateTime *datetime)
18031803* result = j2day (date2j (tm -> tm_year ,tm -> tm_mon ,tm -> tm_mday ));
18041804break ;
18051805
1806+ case DTK_DOY :
1807+ if (datetime2tm (dt ,& tz ,tm ,& fsec ,& tzn )!= 0 )
1808+ elog (WARN ,"Unable to encode datetime" ,NULL );
1809+
1810+ * result = (date2j (tm -> tm_year ,tm -> tm_mon ,tm -> tm_mday )
1811+ - date2j (tm -> tm_year ,1 ,1 )+ 1 );
1812+ break ;
1813+
18061814default :
18071815elog (WARN ,"Datetime units '%s' not supported" ,lowunits );
18081816* result = 0 ;
@@ -2101,6 +2109,7 @@ static datetkn datetktbl[] = {
21012109{"december" ,MONTH ,12 },
21022110{"dnt" ,TZ ,6 },/* Dansk Normal Tid */
21032111{"dow" ,RESERV ,DTK_DOW },/* day of week */
2112+ {"doy" ,RESERV ,DTK_DOY },/* day of year */
21042113{"dst" ,DTZMOD ,6 },
21052114{"east" ,TZ ,NEG (60 )},/* East Australian Std Time */
21062115{"edt" ,DTZ ,NEG (24 )},/* Eastern Daylight Time */
@@ -2674,7 +2683,7 @@ ParseDateTime(char *timestr, char *lowstr,
26742683field [nf ]= lp ;
26752684
26762685/* leading digit? then date or time */
2677- if (isdigit (* cp ))
2686+ if (isdigit (* cp )|| ( * cp == '.' ) )
26782687{
26792688* lp ++ = * cp ++ ;
26802689while (isdigit (* cp ))
@@ -2686,29 +2695,23 @@ ParseDateTime(char *timestr, char *lowstr,
26862695while (isdigit (* cp )|| (* cp == ':' )|| (* cp == '.' ))
26872696* lp ++ = * cp ++ ;
26882697
2689- /* date field? allow embedded text month */
26902698}
2699+ /* date field? allow embedded text month */
26912700else if ((* cp == '-' )|| (* cp == '/' )|| (* cp == '.' ))
26922701{
26932702ftype [nf ]= DTK_DATE ;
26942703while (isalnum (* cp )|| (* cp == '-' )|| (* cp == '/' )|| (* cp == '.' ))
26952704* lp ++ = tolower (* cp ++ );
26962705
2697- /*
2698- * otherwise, number only and will determine year, month,
2699- * or day later
2700- */
27012706}
2707+ /* otherwise, number only and will determine year, month, or day later */
27022708else
27032709{
27042710ftype [nf ]= DTK_NUMBER ;
27052711}
27062712
2707- /*
2708- * text? then date string, month, day of week, special, or
2709- * timezone
2710- */
27112713}
2714+ /* text? then date string, month, day of week, special, or timezone */
27122715else if (isalpha (* cp ))
27132716{
27142717ftype [nf ]= DTK_STRING ;
@@ -3696,6 +3699,9 @@ DecodeSpecial(int field, char *lowtoken, int *val)
36963699 * Interpret previously parsed fields for general time interval.
36973700 * Return 0 if decoded and -1 if problems.
36983701 *
3702+ * Allow "date" field DTK_DATE since this could be just
3703+ * an unsigned floating point number. - thomas 1997-11-16
3704+ *
36993705 * If code is changed to read fields from first to last,
37003706 *then use READ_FORWARD-bracketed code to allow sign
37013707 *to persist to subsequent unsigned fields.
@@ -3709,14 +3715,15 @@ DecodeDateDelta(char *field[], int ftype[], int nf, int *dtype, struct tm * tm,
37093715int is_neg = FALSE;
37103716#endif
37113717
3718+ char * cp ;
37123719int fmask = 0 ,
37133720tmask ,
37143721type ;
37153722int i ,
37163723ii ;
37173724int flen ,
37183725val ;
3719- char * cp ;
3726+ double fval ;
37203727double sec ;
37213728
37223729* dtype = DTK_DELTA ;
@@ -3774,6 +3781,7 @@ DecodeDateDelta(char *field[], int ftype[], int nf, int *dtype, struct tm * tm,
37743781is_neg = (* field [i ]== '-' );
37753782#endif
37763783
3784+ case DTK_DATE :
37773785case DTK_NUMBER :
37783786val = strtol (field [i ],& cp ,10 );
37793787#if READ_FORWARD
@@ -3782,70 +3790,102 @@ DecodeDateDelta(char *field[], int ftype[], int nf, int *dtype, struct tm * tm,
37823790#endif
37833791if (* cp == '.' )
37843792{
3793+ fval = strtod (cp ,& cp );
3794+ if (* cp != '\0' )
3795+ return -1 ;
3796+
3797+ if (val < 0 )
3798+ fval = - (fval );
3799+ #if FALSE
37853800* fsec = strtod (cp ,NULL );
37863801if (val < 0 )
37873802* fsec = - (* fsec );
3803+ #endif
37883804}
3805+ else if (* cp == '\0' )
3806+ fval = 0 ;
3807+ else
3808+ return -1 ;
3809+
37893810flen = strlen (field [i ]);
37903811tmask = 0 ;/* DTK_M(type); */
37913812
37923813switch (type )
37933814{
37943815case DTK_MICROSEC :
3795- * fsec += (val * 1e-6 );
3816+ * fsec += (( val + fval ) * 1e-6 );
37963817break ;
37973818
37983819case DTK_MILLISEC :
3799- * fsec += (val * 1e-3 );
3820+ * fsec += (( val + fval ) * 1e-3 );
38003821break ;
38013822
38023823case DTK_SECOND :
38033824tm -> tm_sec += val ;
3825+ * fsec += fval ;
38043826tmask = DTK_M (SECOND );
38053827break ;
38063828
38073829case DTK_MINUTE :
38083830tm -> tm_min += val ;
3831+ if (fval != 0 )
3832+ tm -> tm_sec += (fval * 60 );
38093833tmask = DTK_M (MINUTE );
38103834break ;
38113835
38123836case DTK_HOUR :
38133837tm -> tm_hour += val ;
3838+ if (fval != 0 )
3839+ tm -> tm_sec += (fval * 3600 );
38143840tmask = DTK_M (HOUR );
38153841break ;
38163842
38173843case DTK_DAY :
38183844tm -> tm_mday += val ;
3845+ if (fval != 0 )
3846+ tm -> tm_sec += (fval * 86400 );
38193847tmask = ((fmask & DTK_M (DAY )) ?0 :DTK_M (DAY ));
38203848break ;
38213849
38223850case DTK_WEEK :
38233851tm -> tm_mday += val * 7 ;
3852+ if (fval != 0 )
3853+ tm -> tm_sec += (fval * (7 * 86400 ));
38243854tmask = ((fmask & DTK_M (DAY )) ?0 :DTK_M (DAY ));
38253855break ;
38263856
38273857case DTK_MONTH :
38283858tm -> tm_mon += val ;
3859+ if (fval != 0 )
3860+ tm -> tm_sec += (fval * (30 * 86400 ));
38293861tmask = DTK_M (MONTH );
38303862break ;
38313863
38323864case DTK_YEAR :
38333865tm -> tm_year += val ;
3866+ if (fval != 0 )
3867+ tm -> tm_mon += (fval * 12 );
38343868tmask = ((fmask & DTK_M (YEAR )) ?0 :DTK_M (YEAR ));
38353869break ;
38363870
38373871case DTK_DECADE :
38383872tm -> tm_year += val * 10 ;
3873+ if (fval != 0 )
3874+ tm -> tm_mon += (fval * 120 );
38393875tmask = ((fmask & DTK_M (YEAR )) ?0 :DTK_M (YEAR ));
38403876break ;
38413877
38423878case DTK_CENTURY :
38433879tm -> tm_year += val * 100 ;
3880+ if (fval != 0 )
3881+ tm -> tm_mon += (fval * 1200 );
38443882tmask = ((fmask & DTK_M (YEAR )) ?0 :DTK_M (YEAR ));
38453883break ;
38463884
38473885case DTK_MILLENIUM :
38483886tm -> tm_year += val * 1000 ;
3887+ if (fval != 0 )
3888+ tm -> tm_mon += (fval * 12000 );
38493889tmask = ((fmask & DTK_M (YEAR )) ?0 :DTK_M (YEAR ));
38503890break ;
38513891