function toLunar(yearOrDate, monthOrResult, day, result) {
        var solarDate;
        var lunarDate;
        if (typeof yearOrDate === "object") {
          solarDate = yearOrDate;
          lunarDate = monthOrResult || {};
        } else {
          var isValidYear = typeof yearOrDate === "number" && yearOrDate >= 1888 && yearOrDate <= 2111;
          if (!isValidYear)
            throw new Error("Solar year outside range 1888-2111");
          var isValidMonth = typeof monthOrResult === "number" && monthOrResult >= 1 && monthOrResult <= 12;
          if (!isValidMonth)
            throw new Error("Solar month outside range 1 - 12");
          var isValidDay = typeof day === "number" && day >= 1 && day <= 31;
          if (!isValidDay)
            throw new Error("Solar day outside range 1 - 31");
          solarDate = {
            year: yearOrDate,
            month: monthOrResult,
            day
          };
          lunarDate = result || {};
        }
        var chineseNewYearPackedDate = CHINESE_NEW_YEAR[solarDate.year - CHINESE_NEW_YEAR[0]];
        var packedDate = solarDate.year << 9 | solarDate.month << 5 | solarDate.day;
        lunarDate.year = packedDate >= chineseNewYearPackedDate ? solarDate.year : solarDate.year - 1;
        chineseNewYearPackedDate = CHINESE_NEW_YEAR[lunarDate.year - CHINESE_NEW_YEAR[0]];
        var y = chineseNewYearPackedDate >> 9 & 4095;
        var m = chineseNewYearPackedDate >> 5 & 15;
        var d = chineseNewYearPackedDate & 31;
        var daysFromNewYear;
        var chineseNewYearJSDate = new Date(y, m - 1, d);
        var jsDate = new Date(solarDate.year, solarDate.month - 1, solarDate.day);
        daysFromNewYear = Math.round(
          (jsDate - chineseNewYearJSDate) / (24 * 3600 * 1e3)
        );
        var monthDaysTable = LUNAR_MONTH_DAYS[lunarDate.year - LUNAR_MONTH_DAYS[0]];
        var i;
        for (i = 0; i < 13; i++) {
          var daysInMonth = monthDaysTable & 1 << 12 - i ? 30 : 29;
          if (daysFromNewYear < daysInMonth) {
            break;
          }
          daysFromNewYear -= daysInMonth;
        }
        var intercalaryMonth = monthDaysTable >> 13;
        if (!intercalaryMonth || i < intercalaryMonth) {
          lunarDate.isIntercalary = false;
          lunarDate.month = 1 + i;
        } else if (i === intercalaryMonth) {
          lunarDate.isIntercalary = true;
          lunarDate.month = i;
        } else {
          lunarDate.isIntercalary = false;
          lunarDate.month = i;
        }
        lunarDate.day = 1 + daysFromNewYear;
        return lunarDate;
      }
Add period(s) to a date.
            Cater for no year zero.
            @memberof ChineseCalendar
            @param date {CDate} The starting date.
            @param offset {number} The number of periods to adjust by.
            @param period {string} One of 'y' for year, 'm' for month, 'w' for week, 'd' for day.
            @return {CDate} The updated date.
            @throws Error if a different calendar used.