private static long julianDateFloor()

in amoro-format-mixed/amoro-mixed-flink/amoro-mixed-flink-common/src/main/java/org/apache/amoro/flink/util/DateTimeUtils.java [1186:1246]


  private static long julianDateFloor(TimeUnitRange range, int julian, boolean floor) {
    // Algorithm the book "Astronomical Algorithms" by Jean Meeus, 1998
    int b = 0;
    int c = 0;
    if (julian > 2299160) {
      int a = julian + 32044;
      b = (4 * a + 3) / 146097;
      c = a - b * 146097 / 4;
    } else {
      b = 0;
      c = julian + 32082;
    }
    int d = (4 * c + 3) / 1461;
    int e = c - (1461 * d) / 4;
    int m = (5 * e + 2) / 153;
    int day = e - (153 * m + 2) / 5 + 1;
    int month = m + 3 - 12 * (m / 10);
    int quarter = (month + 2) / 3;
    int year = b * 100 + d - 4800 + (m / 10);
    switch (range) {
      case MILLENNIUM:
        return floor
            ? ymdToUnixDate(1000 * ((year + 999) / 1000) - 999, 1, 1)
            : ymdToUnixDate(1000 * ((year + 999) / 1000) + 1, 1, 1);
      case CENTURY:
        return floor
            ? ymdToUnixDate(100 * ((year + 99) / 100) - 99, 1, 1)
            : ymdToUnixDate(100 * ((year + 99) / 100) + 1, 1, 1);
      case DECADE:
        return floor
            ? ymdToUnixDate(10 * (year / 10), 1, 1)
            : ymdToUnixDate(10 * (1 + year / 10), 1, 1);
      case YEAR:
        if (!floor && (month > 1 || day > 1)) {
          year += 1;
        }
        return ymdToUnixDate(year, 1, 1);
      case MONTH:
        if (!floor && day > 1) {
          month += 1;
        }
        return ymdToUnixDate(year, month, 1);
      case QUARTER:
        if (!floor && (month > 1 || day > 1)) {
          quarter += 1;
        }
        return ymdToUnixDate(year, quarter * 3 - 2, 1);
      case WEEK:
        int dow = (int) floorMod(julian + 1, 7); // sun=0, sat=6
        int offset = dow;
        if (!floor && offset > 0) {
          offset -= 7;
        }
        return ymdToUnixDate(year, month, day) - offset;
      case DAY:
        int res = ymdToUnixDate(year, month, day);
        return floor ? res : res + 1;
      default:
        throw new AssertionError(range);
    }
  }