in core/src/main/java/org/apache/calcite/avatica/util/DateTimeUtils.java [852:914]
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);
}
}