Checking Calendar Date Validity

A typical call to the date checking boolean function might be symbolized something like:
 IsValidFlag = Is_Valid_Date (ISOymd, CalMode)
It simply returns boolean TRUE for a valid date or boolean FALSE for a bad date.

How To Determine If A Given Date Is A Valid Date On The Calendar

Just because we can easily make up any random calendar date does not necessarily mean that the given date is valid.  When computing with dates, we need a way to filter and detect invalid dates.  For example, May 37 would be invalid on both the Julian and Gregorian calendars in any year because May does not have 37 days in either calendar system.  Nevertheless, the JD number algorithm will return a seemingly valid JD number for such absurd dates.

Another example would be Feb 29th, 2100, which, on our Gregorian calendar, is an invalid date, while at the same time, being a perfectly valid date on the old Julian calendar.  Situations like these need to be taken into account.

Nothing in a JD number value itself indicates that one or more invalid date elements were used to compute it.  Also, the same JD number can result for a valid set of date elements as for any number of invalid sets of date elements as well.

Another problem we may encounter is inconsistent date validity.  For example, the calendar date 1900 February 29 is valid on the Julian calendar, but no such date existed on our Gregorian calendar, so a date can be a valid date on one calendar system while an invalid date on another.

To check a calendar date for validity, we use both the standard JD algorithm and the inverse JD algorithm together.  The date validity testing process is very simple, using these complimentary algorithms.

Here is a way we can do it:
  • First, compute the simple JD number (JD) for the given date and calendar mode arguments (ISOymd, CalMode).
  •  JD = JD_For_ISOymd (ISOymd, CalMode)

  • Next, apply the inverse JD algorithm using the computed JD value and calendar mode as
    the input arguments and compute the check date value (ISOymdCheck).
  •  ISOymdCheck = ISOymd_For_JD (JD, CalMode)

  • Finally, if the computed check date (ISOymdCheck) exactly matches the original date value, then the original date (ISOymd) was valid, otherwise it was invalid.
  •  if (ISOymdCheck == ISOymd) then return TRUE else return FALSE

Algorithm 3

A boolean function algorithm to indicate if a given ISO integer-encoded calendar date (ISOymd, CalMode) is a valid date for the given calendar mode.  Valid = TRUE else FALSE = Invalid
 JD = JD_For_ISOymd (ISOymd, CalMode)

 ISOymdCheck = ISOymd_For_JD (JD, CalMode)

 if (ISOymdCheck == ISOymd) then return TRUE else return FALSE
 ISOymdCheck = ISOymd_For_JD(JD_For_ISOymd(ISOymd, CalMode), CalMode)

 return (ISOymdCheck == ISOymd)? TRUE:FALSE
 return (ISOymd_For_JD(JD_For_ISOymd(ISOymd, CalMode), CalMode) == ISOymd)? TRUE:FALSE 

How It Works

Unlike the Julian Day number algorithm, which can return the same JD number for a variety of dates, invalid or not, the inverse JD algorithm returns only a single date for any given JD number and calendar mode.  This date is always the only valid date corresponding to that JD number and calendar mode.

So, to check a date, we simply compute the JD number from it, then reverse the process based on the computed JD number and we should get back exactly the same date value that produced that JD number.  If not, then the date was invalid. 

Whatever date value results from the inverse JD function, it is the only correct date for that JD argument and it should exactly match the original date.  This feature makes the inverse JD algorithm a valuable tool for easily checking the validity of any given calendar date.


Is the Gregorian calendar date 2100 Feb 29 a valid date?

To find out, we first compute the standard JD number for the given ISOymd and CalMode.
 ISOymd   = 21000229 = 2100 Feb 29
 CalMode  = 1 = Gregorian

 JD = JD_For_ISOymd (ISOymd, CalMode) = 2488129
Then, to test it, we reverse the process, using the JD value we just computed as the input argument to the inverse JD function algorithm.  The returned value will be compared to the original integer-encoded date used to compute the JD number.
 JD = 2488129
 CalMode = 1 (Gregorian)

 ISOymdCheck = ISOymd_For_JD (JD, CalMode)
            = 21000301
Comparing the ISO integer-encoded dates, we have:
 ISOymd      = 21000229  Given date yields JD=2488129
 ISOymdCheck = 21000301  Correct date for JD=2488129
The ISO integer-encoded date values do NOT match.  Therefore the given Gregorian date (2100 Feb 29) is invalid.

Since on the Gregorian calendar (CalMode=1) the year 2100 will not be a leap year, there can be no February 29th that year.  However, on the old Julian calendar (CalMode=0), that same date will be valid, since 2100 on that calendar system will be a leap year.

© Jay Tanner - PHP Science Labs - 2011