Bigkoo/Android-PickerView · error · IllegalArgumentException

Illegal lunar date, must be like that: year …

Error message

Illegal lunar date, must be like that:
	year : 1900~2099
	month : 1~12
	day : 1~30

What it means

This IllegalArgumentException is thrown by LunarCalendar.lunarToSolar when converting a lunar date to a solar date with inputs outside the supported table range. The library's lunar calendar data only covers lunar years 1900-2099, months 1-12, and days 1-30, so any out-of-range value makes the conversion mathematically undefined for this library.

Solutions

  1. Validate the lunar year is within 1900-2099, month 1-12, day 1-30 before calling lunarToSolar
  2. Ensure you are passing lunar-calendar values, not solar Calendar values, to lunarToSolar
  3. Wrap the call in try-catch and fall back to a default in-range date or solar mode
  4. Clamp/normalize out-of-range day values (e.g. day 0 -> 1, day 31 -> 30) if approximate results are acceptable

Example fix

// before
Calendar solar = LunarCalendar.lunarToSolar(2100, 12, 30, false); // throws
// after
if (lunarYear >= 1900 && lunarYear <= 2099 && lunarMonth >= 1 && lunarMonth <= 12 && lunarDay >= 1 && lunarDay <= 30) {
    Calendar solar = LunarCalendar.lunarToSolar(lunarYear, lunarMonth, lunarDay, isLeapMonth);
} else {
    Calendar solar = Calendar.getInstance(); // fallback
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidLunarDate(int year, int month, int day) {
    return year >= 1900 && year <= 2099 && month >= 1 && month <= 12 && day >= 1 && day <= 30;
}

Try / catch

try {
    Calendar solar = LunarCalendar.lunarToSolar(y, m, d, isLeap);
} catch (IllegalArgumentException e) {
    Calendar solar = Calendar.getInstance(); // safe fallback
}

Prevention

When it happens

Trigger: Calling lunarToSolar(year, month, monthDay, isLeapMonth) with year < 1900 or > 2099, month outside 1-12, or day outside 1-30, e.g. passing a Calendar-derived solar year like 2026 into the lunar conversion, or an uninitialized/defaulted day of 0.

Common situations: Feeding Gregorian (solar) dates into the lunar API by mistake; computing a lunar date for a date outside the picker's supported century (e.g. 2100 default range edges); uninitialized int fields defaulting to 0; custom TimePicker configurations that mix solar and lunar mode.

Related errors


AI-assisted analysis of Bigkoo/Android-PickerView@e200d8c063 (2026-09-07). Data as JSON: /api/errors/4a7e7bf652f32efb. Report an issue: GitHub.

Appendix: source

Thrown at pickerview/src/main/java/com/bigkoo/pickerview/utils/LunarCalendar.java:143

    /**
     * 将农历日期转换为公历日期
     *
     * @param year        农历年份
     * @param month       农历月
     * @param monthDay    农历日
     * @param isLeapMonth 该月是否是闰月
     * @return 返回农历日期对应的公历日期,year0, month1, day2.
     */
    public static final int[] lunarToSolar(int year, int month, int monthDay,
                                           boolean isLeapMonth) {
        int dayOffset;
        int leapMonth;
        int i;

        if (year < MIN_YEAR || year > MAX_YEAR || month < 1 || month > 12
                || monthDay < 1 || monthDay > 30) {
            throw new IllegalArgumentException(
                    "Illegal lunar date, must be like that:\n\t" +
                            "year : 1900~2099\n\t" +
                            "month : 1~12\n\t" +
                            "day : 1~30");
        }

        dayOffset = (LUNAR_INFO[year - MIN_YEAR] & 0x001F) - 1;

        if (((LUNAR_INFO[year - MIN_YEAR] & 0x0060) >> 5) == 2)
            dayOffset += 31;

        for (i = 1; i < month; i++) {
            if ((LUNAR_INFO[year - MIN_YEAR] & (0x80000 >> (i - 1))) == 0)
                dayOffset += 29;
            else
                dayOffset += 30;
        }

View on GitHub (pinned to e200d8c063)