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);
}
}