parseDate : (String | Number) -> (String | Number) -> (String | Number) -> { day, month, year }
function parseDate(dayString, monthString, yearString) {
  const initialDate = {
    day: parseAndConstrain(1, 31, dayString),
    month: parseAndConstrain(1, 12, monthString),
    year: parseAndConstrain(1, 2500, yearString),
  };

  const dateIsValid = flow(
    toMilliseconds,
    millisecondsToBreakdownDate,
    parsed => JSON.stringify(initialDate) === JSON.stringify(parsed)
  )(initialDate);

  if (!dateIsValid) {
    // All values have been constrined to their allowed values, the only case
    // in which date could be NaN is the one where the day value is greater than
    // the maximum possible day value of the specified month. Like Feb 31
    // So we will decrease the day and try to parse again. If the day is already
    // quite low, then throw the error.
    assert(
      initialDate.day > 25,
      `An unknown error occurred parsing the date ${
      dayString}/${monthString}/${yearString}`
    );
    return parseDate(initialDate.day - 1, initialDate.month, initialDate.year);
  }

  return initialDate;
}