@Override
  public void exitNthCenturyRange(NthCenturyRangeContext ctx) {
    if (ctx.exception != null) return;

    Era era = (Era) stack.pop();
    Integer endN = (Integer) stack.pop();
    Part endPart = (Part) stack.pop();
    Integer startN = (Integer) stack.pop();
    Part startPart = (Part) stack.pop();

    if (era == null) {
      era = Date.DEFAULT_ERA;
    }

    int startYear = DateUtils.nthCenturyToYear(startN);
    int endYear = DateUtils.nthCenturyToYear(endN);

    stack.push(
        startPart == null
            ? DateUtils.getCenturyStartDate(startYear, era)
            : DateUtils.getPartialCenturyStartDate(startYear, startPart, era));
    stack.push(
        startPart == null
            ? DateUtils.getCenturyEndDate(startYear, era)
            : DateUtils.getPartialCenturyEndDate(startYear, startPart, era));
    stack.push(
        endPart == null
            ? DateUtils.getCenturyStartDate(endYear, era)
            : DateUtils.getPartialCenturyStartDate(endYear, endPart, era));
    stack.push(
        endPart == null
            ? DateUtils.getCenturyEndDate(endYear, era)
            : DateUtils.getPartialCenturyEndDate(endYear, endPart, era));
  }
  @Override
  public void exitPartialCentury(PartialCenturyContext ctx) {
    if (ctx.exception != null) return;

    Era era = (Era) stack.pop();
    Integer year = (Integer) stack.pop();
    Part part = (Part) stack.pop();

    if (era != null) {
      // If the era was explicitly specified, the start and end years
      // may be calculated now.

      stack.push(DateUtils.getPartialCenturyStartDate(year, part, era));
      stack.push(DateUtils.getPartialCenturyEndDate(year, part, era));
    } else {
      // If the era was not explicitly specified, the start and end years
      // can't be calculated yet. The calculation must be deferred until
      // later. For example, this partial century may be the start of a hyphenated
      // range, where the era will be inherited from the era of the end of
      // the range; this era won't be known until farther up the parse tree,
      // when both sides of the range will have been parsed.

      stack.push(new DeferredPartialCenturyStartDate(year, part));
      stack.push(new DeferredPartialCenturyEndDate(year, part));
    }
  }