summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/dt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/dt.c')
-rw-r--r--src/backend/utils/adt/dt.c385
1 files changed, 289 insertions, 96 deletions
diff --git a/src/backend/utils/adt/dt.c b/src/backend/utils/adt/dt.c
index f56eb68a5f..28f31a1472 100644
--- a/src/backend/utils/adt/dt.c
+++ b/src/backend/utils/adt/dt.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.13 1997/03/28 07:16:59 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.14 1997/04/02 18:33:32 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
#include <errno.h>
#include "postgres.h"
-#include <miscadmin.h>
+#include "miscadmin.h"
#ifdef HAVE_FLOAT_H
# include <float.h>
#endif
@@ -34,6 +34,10 @@
#define USE_DATE_CACHE 1
+#define isleap(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
+
+int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
+
char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
@@ -55,26 +59,26 @@ datetime_in(char *str)
double fsec;
struct tm tt, *tm = &tt;
- int tzp;
+ int tz;
int dtype;
int nf;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN];
+ char lowstr[MAXDATELEN+1];
if (!PointerIsValid(str))
- elog(WARN, "Bad (null) datetime external representation", NULL);
+ elog(WARN,"Bad (null) datetime external representation",NULL);
if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
- || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tzp) != 0))
+ || (DecodeDateTime( field, ftype, nf, &dtype, tm, &fsec, &tz) != 0))
elog(WARN,"Bad datetime external representation %s",str);
if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
- elog(WARN, "Memory allocation failed, can't input datetime '%s'",str);
+ elog(WARN,"Memory allocation failed, can't input datetime '%s'",str);
switch (dtype) {
case DTK_DATE:
- *result = tm2datetime( tm, fsec, tzp);
+ *result = tm2datetime( tm, fsec, &tz);
#ifdef DATEDEBUG
printf( "datetime_in- date is %f\n", *result);
@@ -103,7 +107,7 @@ printf( "datetime_in- date is %f\n", *result);
break;
default:
- elog(WARN, "Internal coding error, can't input datetime '%s'",str);
+ elog(WARN,"Internal coding error, can't input datetime '%s'",str);
};
return(result);
@@ -118,7 +122,7 @@ datetime_out(DateTime *dt)
char *result;
struct tm tt, *tm = &tt;
double fsec;
- char buf[MAXDATELEN];
+ char buf[MAXDATELEN+1];
if (!PointerIsValid(dt))
return(NULL);
@@ -126,7 +130,7 @@ datetime_out(DateTime *dt)
if (DATETIME_IS_RESERVED(*dt)) {
EncodeSpecialDateTime(*dt, buf);
- } else if (datetime2tm( *dt, tm, &fsec) == 0) {
+ } else if (datetime2tm( *dt, &CTimeZone, tm, &fsec) == 0) {
EncodeDateTime(tm, fsec, DateStyle, buf);
} else {
@@ -134,7 +138,7 @@ datetime_out(DateTime *dt)
};
if (!PointerIsValid(result = PALLOC(strlen(buf)+1)))
- elog(WARN, "Memory allocation failed, can't output datetime", NULL);
+ elog(WARN,"Memory allocation failed, can't output datetime",NULL);
strcpy( result, buf);
@@ -159,7 +163,7 @@ timespan_in(char *str)
int nf;
char *field[MAXDATEFIELDS];
int ftype[MAXDATEFIELDS];
- char lowstr[MAXDATELEN];
+ char lowstr[MAXDATELEN+1];
tm->tm_year = 0;
tm->tm_mon = 0;
@@ -170,14 +174,14 @@ timespan_in(char *str)
fsec = 0;
if (!PointerIsValid(str))
- elog(WARN, "Bad (null) timespan external representation", NULL);
+ elog(WARN,"Bad (null) timespan external representation",NULL);
if ((ParseDateTime( str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
|| (DecodeDateDelta( field, ftype, nf, &dtype, tm, &fsec) != 0))
elog(WARN,"Bad timespan external representation %s",str);
if (!PointerIsValid(span = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't input timespan '%s'",str);
+ elog(WARN,"Memory allocation failed, can't input timespan '%s'",str);
switch (dtype) {
case DTK_DELTA:
@@ -189,7 +193,7 @@ timespan_in(char *str)
break;
default:
- elog(WARN, "Internal coding error, can't input timespan '%s'",str);
+ elog(WARN,"Internal coding error, can't input timespan '%s'",str);
};
return(span);
@@ -205,7 +209,7 @@ timespan_out(TimeSpan *span)
struct tm tt, *tm = &tt;
double fsec;
- char buf[MAXDATELEN];
+ char buf[MAXDATELEN+1];
if (!PointerIsValid(span))
return(NULL);
@@ -229,6 +233,26 @@ timespan_out(TimeSpan *span)
*****************************************************************************/
+bool
+datetime_finite(DateTime *datetime)
+{
+ if (!PointerIsValid(datetime))
+ return FALSE;
+
+ return(! DATETIME_NOT_FINITE(*datetime));
+} /* datetime_finite() */
+
+
+bool
+timespan_finite(TimeSpan *timespan)
+{
+ if (!PointerIsValid(timespan))
+ return FALSE;
+
+ return(! TIMESPAN_NOT_FINITE(*timespan));
+} /* timespan_finite() */
+
+
/*----------------------------------------------------------
* Relational operators for datetime.
*---------------------------------------------------------*/
@@ -267,14 +291,14 @@ SetDateTime( DateTime dt) {
if (DATETIME_IS_CURRENT(dt)) {
GetCurrentTime(&tt);
- dt = tm2datetime( &tt, 0, 0);
+ dt = tm2datetime( &tt, 0, NULL);
#ifdef DATEDEBUG
printf( "SetDateTime- current time is %f\n", dt);
#endif
} else { /* if (DATETIME_IS_EPOCH(dt1)) */
GetEpochTime(&tt);
- dt = tm2datetime( &tt, 0, 0);
+ dt = tm2datetime( &tt, 0, NULL);
#ifdef DATEDEBUG
printf( "SetDateTime- epoch time is %f\n", dt);
#endif
@@ -520,7 +544,7 @@ TimeSpan *datetime_sub(DateTime *datetime1, DateTime *datetime2)
dt2 = *datetime2;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't subtract dates",NULL);
+ elog(WARN,"Memory allocation failed, can't subtract dates",NULL);
if (DATETIME_IS_RELATIVE(dt1)) dt1 = SetDateTime(dt1);
if (DATETIME_IS_RELATIVE(dt2)) dt2 = SetDateTime(dt2);
@@ -538,46 +562,83 @@ TimeSpan *datetime_sub(DateTime *datetime1, DateTime *datetime2)
} /* datetime_sub() */
+/* datetime_add_span()
+ * Add a timespan to a datetime data type.
+ * Note that timespan has provisions for qualitative year/month
+ * units, so try to do the right thing with them.
+ * To add a month, increment the month, and use the same day of month.
+ * Then, if the next month has fewer days, set the day of month
+ * to the last day of month.
+ */
DateTime *datetime_add_span(DateTime *datetime, TimeSpan *span)
{
DateTime *result;
+#if FALSE
double date, time;
int year, mon, mday;
+#endif
if ((!PointerIsValid(datetime)) || (!PointerIsValid(span)))
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(DateTime)))
- elog(WARN, "Memory allocation failed, can't add dates",NULL);
+ elog(WARN,"Memory allocation failed, can't add dates",NULL);
#ifdef DATEDEBUG
-printf( "date_add- add %f to %d %f\n", *datetime, span->month, span->time);
-#endif
-
- *result = *datetime;
- if (DATETIME_IS_RELATIVE(*result)) *result = SetDateTime(*result);
-
- if (span->month != 0) {
- time = JROUND(modf( (*result/86400), &date)*86400);
- date += date2j(2000,1,1);
-
- j2date( ((int) date), &year, &mon, &mday);
- mon += span->month;
- if (mon > 12) {
- year += mon / 12;
- mon %= 12;
- } else if (mon < 0) {
- year += mon / 12;
- mon %= 12;
- year -= 1;
- mon += 12;
+printf( "datetime_add_span- add %f to %d %f\n", *datetime, span->month, span->time);
+#endif
+
+ if (DATETIME_NOT_FINITE(*datetime)) {
+ *result = *datetime;
+
+ } else if (TIMESPAN_IS_INVALID(*span)) {
+ DATETIME_INVALID(*result);
+
+ } else {
+ *result = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
+
+ if (span->month != 0) {
+ struct tm tt, *tm = &tt;
+ double fsec;
+
+ if (datetime2tm( *result, NULL, tm, &fsec) == 0) {
+#ifdef DATEDEBUG
+printf( "datetime_add_span- date was %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+#endif
+ tm->tm_mon += span->month;
+ if (tm->tm_mon > 12) {
+ tm->tm_year += (tm->tm_mon / 12);
+ tm->tm_mon = (tm->tm_mon % 12);
+ } else if (tm->tm_mon < 1) {
+ tm->tm_year += ((tm->tm_mon / 12) - 1);
+ tm->tm_mon = ((tm->tm_mon % 12) + 12);
+ };
+
+ /* adjust for end of month boundary problems... */
+ if (tm->tm_mday > mdays[ tm->tm_mon-1]) {
+ if ((tm->tm_mon == 2) && isleap( tm->tm_year)) {
+ tm->tm_mday = (mdays[ tm->tm_mon-1]+1);
+ } else {
+ tm->tm_mday = mdays[ tm->tm_mon-1];
+ };
+ };
+
+#ifdef DATEDEBUG
+printf( "datetime_add_span- date becomes %d.%02d.%02d\n", tm->tm_year, tm->tm_mon, tm->tm_mday);
+#endif
+ *result = tm2datetime( tm, fsec, NULL);
+
+ } else {
+ DATETIME_INVALID(*result);
+ };
};
- *result += ((date2j( year, mon, mday)-date2j(2000,1,1))*86400);
- *result += time;
- };
- *result = JROUND(*result + span->time);
+#if FALSE
+ *result = JROUND(*result + span->time);
+#endif
+ *result += span->time;
+ };
return(result);
} /* datetime_add_span() */
@@ -607,13 +668,13 @@ TimeSpan *timespan_um(TimeSpan *timespan)
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't subtract dates",NULL);
+ elog(WARN,"Memory allocation failed, can't subtract dates",NULL);
result->time = -(timespan->time);
result->month = -(timespan->month);
return(result);
-} /* datetime_sub() */
+} /* timespan_um() */
TimeSpan *timespan_add(TimeSpan *span1, TimeSpan *span2)
@@ -624,7 +685,7 @@ TimeSpan *timespan_add(TimeSpan *span1, TimeSpan *span2)
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't add timespans",NULL);
+ elog(WARN,"Memory allocation failed, can't add timespans",NULL);
result->month = (span1->month + span2->month);
result->time = JROUND(span1->time + span2->time);
@@ -640,7 +701,7 @@ TimeSpan *timespan_sub(TimeSpan *span1, TimeSpan *span2)
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(TimeSpan)))
- elog(WARN, "Memory allocation failed, can't subtract timespans",NULL);
+ elog(WARN,"Memory allocation failed, can't subtract timespans",NULL);
result->month = (span1->month - span2->month);
result->time = JROUND(span1->time - span2->time);
@@ -654,6 +715,125 @@ TimeSpan *timespan_sub(TimeSpan *span1, TimeSpan *span2)
*---------------------------------------------------------*/
+/* datetime_text()
+ * Convert datetime to text data type.
+ */
+text *
+datetime_text(DateTime *datetime)
+{
+ text *result;
+ char *str;
+ int len;
+
+ if (!PointerIsValid(datetime))
+ return NULL;
+
+ str = datetime_out(datetime);
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ len = (strlen(str)+VARHDRSZ);
+
+ if (!PointerIsValid(result = PALLOC(len)))
+ elog(WARN,"Memory allocation failed, can't convert datetime to text",NULL);
+
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), str, (len-VARHDRSZ));
+
+ PFREE(str);
+
+ return(result);
+} /* datetime_text() */
+
+
+/* text_datetime()
+ * Convert text string to datetime.
+ * Text type is not null terminated, so use temporary string
+ * then call the standard input routine.
+ */
+DateTime *
+text_datetime(text *str)
+{
+ DateTime *result;
+ int i;
+ char *sp, *dp, dstr[MAXDATELEN+1];
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ sp = VARDATA(str);
+ dp = dstr;
+ for (i = 0; i < (VARSIZE(str)-VARHDRSZ); i++) *dp++ = *sp++;
+ *dp = '\0';
+
+ result = datetime_in(dstr);
+
+ return(result);
+} /* text_datetime() */
+
+
+/* timespan_text()
+ * Convert timespan to text data type.
+ */
+text *
+timespan_text(TimeSpan *timespan)
+{
+ text *result;
+ char *str;
+ int len;
+
+ if (!PointerIsValid(timespan))
+ return NULL;
+
+ str = timespan_out(timespan);
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ len = (strlen(str)+VARHDRSZ);
+
+ if (!PointerIsValid(result = PALLOC(len)))
+ elog(WARN,"Memory allocation failed, can't convert timespan to text",NULL);
+
+ VARSIZE(result) = len;
+ memmove(VARDATA(result), str, (len-VARHDRSZ));
+
+ PFREE(str);
+
+ return(result);
+} /* timespan_text() */
+
+
+/* text_timespan()
+ * Convert text string to timespan.
+ * Text type may not be null terminated, so copy to temporary string
+ * then call the standard input routine.
+ */
+TimeSpan *
+text_timespan(text *str)
+{
+ TimeSpan *result;
+ int i;
+ char *sp, *dp, dstr[MAXDATELEN+1];
+
+ if (!PointerIsValid(str))
+ return NULL;
+
+ sp = VARDATA(str);
+ dp = dstr;
+ for (i = 0; i < (VARSIZE(str)-VARHDRSZ); i++) *dp++ = *sp++;
+ *dp = '\0';
+
+ result = timespan_in(dstr);
+
+ return(result);
+} /* text_timespan() */
+
+
+/* datetime_part()
+ * Extract specified field from datetime.
+ */
float64
datetime_part(text *units, DateTime *datetime)
{
@@ -662,7 +842,7 @@ datetime_part(text *units, DateTime *datetime)
DateTime dt;
int type, val;
int i;
- char *up, *lp, lowunits[MAXDATELEN];
+ char *up, *lp, lowunits[MAXDATELEN+1];
double fsec;
struct tm tt, *tm = &tt;
@@ -670,7 +850,7 @@ datetime_part(text *units, DateTime *datetime)
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(float64data)))
- elog(WARN, "Memory allocation failed, can't get date part",NULL);
+ elog(WARN,"Memory allocation failed, can't get date part",NULL);
up = VARDATA(units);
lp = lowunits;
@@ -694,7 +874,7 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
dt = (DATETIME_IS_RELATIVE(*datetime)? SetDateTime(*datetime): *datetime);
- if (datetime2tm( dt, tm, &fsec) == 0) {
+ if (datetime2tm( dt, &CTimeZone, tm, &fsec) == 0) {
switch (val) {
case DTK_TZ:
*result = CTimeZone;
@@ -768,6 +948,9 @@ printf( "datetime_part- units %s type=%d value=%d\n", lowunits, type, val);
} /* datetime_part() */
+/* timespan_part()
+ * Extract specified field from timespan.
+ */
float64
timespan_part(text *units, TimeSpan *timespan)
{
@@ -775,7 +958,7 @@ timespan_part(text *units, TimeSpan *timespan)
int type, val;
int i;
- char *up, *lp, lowunits[MAXDATELEN];
+ char *up, *lp, lowunits[MAXDATELEN+1];
double fsec;
struct tm tt, *tm = &tt;
@@ -783,7 +966,7 @@ timespan_part(text *units, TimeSpan *timespan)
return NULL;
if (!PointerIsValid(result = PALLOCTYPE(float64data)))
- elog(WARN, "Memory allocation failed, can't get date part",NULL);
+ elog(WARN,"Memory allocation failed, can't get date part",NULL);
up = VARDATA(units);
lp = lowunits;
@@ -879,10 +1062,6 @@ printf( "timespan_part- units %s type=%d value=%d\n", lowunits, type, val);
* PRIVATE ROUTINES *
*****************************************************************************/
-#if USE_NEW_TIME_CODE
-#define DATE_MAXLEN 47
-#endif
-
/* definitions for squeezing values into "value" */
#define ABS_SIGNBIT 0200
#define VALMASK 0177
@@ -1218,11 +1397,12 @@ int j2day( int date)
* Also, month is one-based, _not_ zero-based.
*/
int
-datetime2tm( DateTime dt, struct tm *tm, double *fsec)
+datetime2tm( DateTime dt, int *tzp, struct tm *tm, double *fsec)
{
double date, time, sec;
- time = (modf( dt2local( dt, CTimeZone)/86400, &date)*86400);
+ if (tzp != NULL) dt = dt2local( dt, *tzp);
+ time = (modf( dt/86400, &date)*86400);
date += date2j(2000,1,1);
if (time < 0) {
time += 86400;
@@ -1233,7 +1413,8 @@ datetime2tm( DateTime dt, struct tm *tm, double *fsec)
if (date < 0) return -1;
#ifdef DATEDEBUG
-printf( "datetime2tm- date is %f (%f %f)\n", dt, date, time);
+printf( "datetime2tm- date is %f (%f %f)\n",
+ ((tzp != NULL)? dt2local(dt, -(*tzp)): dt), date, time);
#endif
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
@@ -1254,8 +1435,8 @@ printf( "datetime2tm- time is %02d:%02d:%02d %.7f\n", tm->tm_hour, tm->tm_min, t
tm->tm_isdst = -1;
#ifdef DATEDEBUG
-printf( "datetime2tm- timezone is %s; offset is %d; daylight is %d\n",
- CTZName, CTimeZone, CDayLight);
+printf( "datetime2tm- timezone is %s; offset is %d (%d); daylight is %d\n",
+ CTZName, ((tzp != NULL)? *tzp: 0), CTimeZone, CDayLight);
#endif
return 0;
@@ -1268,7 +1449,7 @@ printf( "datetime2tm- timezone is %s; offset is %d; daylight is %d\n",
* Also, month is one-based, _not_ zero-based.
*/
DateTime
-tm2datetime( struct tm *tm, double fsec, int tzp) {
+tm2datetime( struct tm *tm, double fsec, int *tzp) {
DateTime result;
double date, time;
@@ -1284,7 +1465,7 @@ tm2datetime( struct tm *tm, double fsec, int tzp) {
printf( "tm2datetime- date is %f (%f %f %d)\n", result, date, time, (((tm->tm_hour*60)+tm->tm_min)*60+tm->tm_sec));
printf( "tm2datetime- time is %f %02d:%02d:%02d %f\n", time, tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
#endif
- if (tzp != 0) result = dt2local(result, -tzp);
+ if (tzp != NULL) result = dt2local(result, -(*tzp));
return(result);
} /* tm2datetime() */
@@ -1832,30 +2013,14 @@ DecodeDate(char *str, int fmask, int *tmask, struct tm *tm)
*tmask = 0;
+ /* look first for text fields, since that will be unambiguous month */
for (i = 0; i < nf; i++) {
- str = field[i];
- len = strlen(str);
-
- if (len <= 0)
- return -1;
-
- if (isdigit(*str)) {
- if (DecodeNumber( len, str, fmask, &dmask, tm, &fsec) != 0)
- return -1;
-
- } else if (isalpha(*str)) {
+ if (isalpha(*field[i])) {
type = DecodeSpecial( i, field[i], &val);
if (type == IGNORE) continue;
dmask = DTK_M(type);
switch (type) {
- case YEAR:
-#ifdef DATEDEBUG
-printf( "DecodeDate- year field %s value is %d\n", field[i], val);
-#endif
- tm->tm_mon = val;
- break;
-
case MONTH:
#ifdef DATEDEBUG
printf( "DecodeDate- month field %s value is %d\n", field[i], val);
@@ -1863,20 +2028,31 @@ printf( "DecodeDate- month field %s value is %d\n", field[i], val);
tm->tm_mon = val;
break;
- case DAY:
-#ifdef DATEDEBUG
-printf( "DecodeDate- month field %s value is %d\n", field[i], val);
-#endif
- tm->tm_mon = val;
- break;
-
default:
#ifdef DATEDEBUG
printf( "DecodeDate- illegal field %s value is %d\n", field[i], val);
#endif
return -1;
};
+ if (fmask & dmask) return -1;
+
+ fmask |= dmask;
+ *tmask |= dmask;
+
+ /* mark this field as being completed */
+ field[i] = NULL;
};
+ };
+
+ /* now pick up remaining numeric fields */
+ for (i = 0; i < nf; i++) {
+ if (field[i] == NULL) continue;
+
+ if ((len = strlen(field[i])) <= 0)
+ return -1;
+
+ if (DecodeNumber( len, field[i], fmask, &dmask, tm, &fsec) != 0)
+ return -1;
if (fmask & dmask) return -1;
@@ -1955,6 +2131,19 @@ printf( "DecodeNumber- %s is %d fmask=%08x tmask=%08x\n", str, val, fmask, *tmas
printf( "DecodeNumber- match %d (%s) as year\n", val, str);
#endif
*tmask = DTK_M(YEAR);
+
+ /* already have a year? then see if we can substitute... */
+ if (fmask & DTK_M(YEAR)) {
+ if ((!(fmask & DTK_M(DAY)))
+ && ((tm->tm_year >= 1) && (tm->tm_year <= 31))) {
+#ifdef DATEDEBUG
+printf( "DecodeNumber- misidentified year previously; swap with day %d\n", tm->tm_mday);
+#endif
+ tm->tm_mday = tm->tm_year;
+ *tmask = DTK_M(DAY);
+ };
+ };
+
tm->tm_year = val;
/* special case day of year? */
@@ -1966,7 +2155,7 @@ printf( "DecodeNumber- match %d (%s) as year\n", val, str);
&tm->tm_year,&tm->tm_mon,&tm->tm_mday);
/* already have year? then could be month */
- } else if ((fmask && DTK_M(YEAR)) && (! (fmask & DTK_M(MONTH)))
+ } else if ((fmask & DTK_M(YEAR)) && (! (fmask & DTK_M(MONTH)))
&& ((val >= 1) && (val <= 12))) {
#ifdef DATEDEBUG
printf( "DecodeNumber- match %d (%s) as month\n", val, str);
@@ -1975,11 +2164,7 @@ printf( "DecodeNumber- match %d (%s) as month\n", val, str);
tm->tm_mon = val;
/* no year and EuroDates enabled? then could be day */
-#if USE_EURODATES
} else if ((EuroDates || (fmask & DTK_M(MONTH)))
-#else
- } else if ((fmask & DTK_M(MONTH))
-#endif
&& (! ((fmask & DTK_M(YEAR)) && (fmask & DTK_M(DAY))))
&& ((val >= 1) && (val <= 31))) {
#ifdef DATEDEBUG
@@ -1996,6 +2181,14 @@ printf( "DecodeNumber- (2) match %d (%s) as month\n", val, str);
*tmask = DTK_M(MONTH);
tm->tm_mon = val;
+ } else if ((! (fmask & DTK_M(DAY)))
+ && ((val >= 1) && (val <= 31))) {
+#ifdef DATEDEBUG
+printf( "DecodeNumber- (2) match %d (%s) as day\n", val, str);
+#endif
+ *tmask = DTK_M(DAY);
+ tm->tm_mday = val;
+
} else if (! (fmask & DTK_M(YEAR))) {
#ifdef DATEDEBUG
printf( "DecodeNumber- (2) match %d (%s) as year\n", val, str);
@@ -2467,7 +2660,7 @@ int EncodeDateTime(struct tm *tm, double fsec, int style, char *str)
int day, hour, min;
double sec;
#ifdef DATEDEBUG
- char buf[MAXDATELEN];
+ char buf[MAXDATELEN+1];
#endif
sec = (tm->tm_sec + fsec);