@@ -42,7 +42,7 @@ static intDecodeTimezone(char *str, int *tzp);
4242static const datetkn * datebsearch (const char * key ,const datetkn * base ,int nel );
4343static int DecodeDate (char * str ,int fmask ,int * tmask ,bool * is2digits ,
4444struct pg_tm * tm );
45- static int ValidateDate (int fmask ,bool is2digits ,bool bc ,
45+ static int ValidateDate (int fmask ,bool isjulian , bool is2digits ,bool bc ,
4646struct pg_tm * tm );
4747static void TrimTrailingZeros (char * str );
4848static void AppendSeconds (char * cp ,int sec ,fsec_t fsec ,
@@ -795,6 +795,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
795795int dterr ;
796796int mer = HR24 ;
797797bool haveTextMonth = FALSE;
798+ bool isjulian = FALSE;
798799bool is2digits = FALSE;
799800bool bc = FALSE;
800801pg_tz * namedTz = NULL ;
@@ -833,10 +834,12 @@ DecodeDateTime(char **field, int *ftype, int nf,
833834
834835errno = 0 ;
835836val = strtoi (field [i ],& cp ,10 );
836- if (errno == ERANGE )
837+ if (errno == ERANGE || val < 0 )
837838return DTERR_FIELD_OVERFLOW ;
838839
839840j2date (val ,& tm -> tm_year ,& tm -> tm_mon ,& tm -> tm_mday );
841+ isjulian = TRUE;
842+
840843/* Get the time zone from the end of the string */
841844dterr = DecodeTimezone (cp ,tzp );
842845if (dterr )
@@ -1065,11 +1068,13 @@ DecodeDateTime(char **field, int *ftype, int nf,
10651068break ;
10661069
10671070case DTK_JULIAN :
1068- /***
1069- * previous field was a label for "julian date"?
1070- ***/
1071+ /* previous field was a label for "julian date" */
1072+ if ( val < 0 )
1073+ return DTERR_FIELD_OVERFLOW ;
10711074tmask = DTK_DATE_M ;
10721075j2date (val ,& tm -> tm_year ,& tm -> tm_mon ,& tm -> tm_mday );
1076+ isjulian = TRUE;
1077+
10731078/* fractional Julian Day? */
10741079if (* cp == '.' )
10751080{
@@ -1361,7 +1366,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
13611366}/* end loop over fields */
13621367
13631368/* do final checking/adjustment of Y/M/D fields */
1364- dterr = ValidateDate (fmask ,is2digits ,bc ,tm );
1369+ dterr = ValidateDate (fmask ,isjulian , is2digits ,bc ,tm );
13651370if (dterr )
13661371return dterr ;
13671372
@@ -1564,6 +1569,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
15641569int i ;
15651570int val ;
15661571int dterr ;
1572+ bool isjulian = FALSE;
15671573bool is2digits = FALSE;
15681574bool bc = FALSE;
15691575int mer = HR24 ;
@@ -1795,11 +1801,13 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
17951801break ;
17961802
17971803case DTK_JULIAN :
1798- /***
1799- * previous field was a label for "julian date"?
1800- ***/
1804+ /* previous field was a label for "julian date" */
1805+ if ( val < 0 )
1806+ return DTERR_FIELD_OVERFLOW ;
18011807tmask = DTK_DATE_M ;
18021808j2date (val ,& tm -> tm_year ,& tm -> tm_mon ,& tm -> tm_mday );
1809+ isjulian = TRUE;
1810+
18031811if (* cp == '.' )
18041812{
18051813double time ;
@@ -2045,7 +2053,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
20452053}/* end loop over fields */
20462054
20472055/* do final checking/adjustment of Y/M/D fields */
2048- dterr = ValidateDate (fmask ,is2digits ,bc ,tm );
2056+ dterr = ValidateDate (fmask ,isjulian , is2digits ,bc ,tm );
20492057if (dterr )
20502058return dterr ;
20512059
@@ -2247,11 +2255,16 @@ DecodeDate(char *str, int fmask, int *tmask, bool *is2digits,
22472255 * Return 0 if okay, a DTERR code if not.
22482256 */
22492257static int
2250- ValidateDate (int fmask ,bool is2digits ,bool bc ,struct pg_tm * tm )
2258+ ValidateDate (int fmask ,bool isjulian ,bool is2digits ,bool bc ,
2259+ struct pg_tm * tm )
22512260{
22522261if (fmask & DTK_M (YEAR ))
22532262{
2254- if (bc )
2263+ if (isjulian )
2264+ {
2265+ /* tm_year is correct and should not be touched */
2266+ }
2267+ else if (bc )
22552268{
22562269/* there is no year zero in AD/BC notation */
22572270if (tm -> tm_year <=0 )