private static int julianExtract()

in core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java [886:948]


  private static int julianExtract(TimeUnitRange range, int julian) {
    // this shifts the epoch back to astronomical year -4800 instead of the
    // start of the Christian era in year AD 1 of the proleptic Gregorian
    // calendar.
    int j = julian + 32044;
    int g = j / 146097;
    int dg = j % 146097;
    int c = (dg / 36524 + 1) * 3 / 4;
    int dc = dg - c * 36524;
    int b = dc / 1461;
    int db = dc % 1461;
    int a = (db / 365 + 1) * 3 / 4;
    int da = db - a * 365;

    // integer number of full years elapsed since March 1, 4801 BC
    int y = g * 400 + c * 100 + b * 4 + a;
    // integer number of full months elapsed since the last March 1
    int m = (da * 5 + 308) / 153 - 2;
    // number of days elapsed since day 1 of the month
    int d = da - (m + 4) * 153 / 5 + 122;
    int year = y - 4800 + (m + 2) / 12;
    int month = (m + 2) % 12 + 1;
    int day = d + 1;
    switch (range) {
    case YEAR:
      return year;
    case ISOYEAR:
      int weekNumber = getIso8601WeekNumber(julian, year, month, day);
      if (weekNumber == 1 && month == 12) {
        return year + 1;
      } else if (month == 1 && weekNumber > 50) {
        return year - 1;
      }
      return year;
    case QUARTER:
      return (month + 2) / 3;
    case MONTH:
      return month;
    case DAY:
      return day;
    case DOW:
      return Math.floorMod(julian + 1, 7) + 1; // sun=1, sat=7
    case ISODOW:
      return Math.floorMod(julian, 7) + 1; // mon=1, sun=7
    case WEEK:
      return getIso8601WeekNumber(julian, year, month, day);
    case DOY:
      final long janFirst = ymdToJulian(year, 1, 1);
      return (int) (julian - janFirst) + 1;
    case DECADE:
      return year / 10;
    case CENTURY:
      return year > 0
          ? (year + 99) / 100
          : (year - 99) / 100;
    case MILLENNIUM:
      return year > 0
          ? (year + 999) / 1000
          : (year - 999) / 1000;
    default:
      throw new AssertionError(range);
    }
  }