public static LunarDate SolarToLunar(DateTime date, int timeZone)
        {
            long k, dayNumber, monthStart, a11, b11, lunarDay, lunarMonth, lunarYear, diff, leapMonthDiff;
            bool lunarLeap;

            dayNumber  = LunarYearTools.jdFromDate(date.Day, date.Month, date.Year);
            k          = LunarYearTools.INT((dayNumber - 2415021.076998695) / 29.530588853);
            monthStart = LunarYearTools.getNewMoonDay(k + 1, timeZone);
            if (monthStart > dayNumber)
            {
                monthStart = LunarYearTools.getNewMoonDay(k, timeZone);
            }
            // alert(dayNumber+" -> "+monthStart);
            a11 = LunarYearTools.getLunarMonth11(date.Year, timeZone);
            b11 = a11;
            if (a11 >= monthStart)
            {
                lunarYear = date.Year;
                a11       = LunarYearTools.getLunarMonth11(date.Year - 1, timeZone);
            }
            else
            {
                lunarYear = date.Year + 1;
                b11       = LunarYearTools.getLunarMonth11(date.Year + 1, timeZone);
            }
            lunarDay   = dayNumber - monthStart + 1;
            diff       = LunarYearTools.INT((monthStart - a11) / 29);
            lunarLeap  = false;
            lunarMonth = diff + 11;
            if (b11 - a11 > 365)
            {
                leapMonthDiff = LunarYearTools.getLeapMonthOffset(a11, timeZone);
                if (diff >= leapMonthDiff)
                {
                    lunarMonth = diff + 10;
                    if (diff == leapMonthDiff)
                    {
                        lunarLeap = true;
                    }
                }
            }
            if (lunarMonth > 12)
            {
                lunarMonth = lunarMonth - 12;
            }
            if (lunarMonth >= 11 && diff < 4)
            {
                lunarYear -= 1;
            }
            return(new LunarDate((int)lunarDay, (int)lunarMonth, (int)lunarYear, lunarLeap));
        }
        public static DateTime LunarToSolar(LunarDate ld, int timeZone)
        {
            long k, a11, b11, off, leapOff, leapMonth, monthStart;

            if (ld.Month < 11)
            {
                a11 = LunarYearTools.getLunarMonth11(ld.Year - 1, timeZone);
                b11 = LunarYearTools.getLunarMonth11(ld.Year, timeZone);
            }
            else
            {
                a11 = LunarYearTools.getLunarMonth11(ld.Year, timeZone);
                b11 = LunarYearTools.getLunarMonth11(ld.Year + 1, timeZone);
            }
            k   = LunarYearTools.INT(0.5 + (a11 - 2415021.076998695) / 29.530588853);
            off = ld.Month - 11;
            if (off < 0)
            {
                off += 12;
            }
            if (b11 - a11 > 365)
            {
                leapOff   = LunarYearTools.getLeapMonthOffset(a11, timeZone);
                leapMonth = leapOff - 2;
                if (leapMonth < 0)
                {
                    leapMonth += 12;
                }
                if (ld.IsLeapYear && ld.Month != leapMonth)
                {
                    return(DateTime.MinValue);
                }
                else if (ld.IsLeapYear || off >= leapOff)
                {
                    off += 1;
                }
            }
            monthStart = LunarYearTools.getNewMoonDay(k + off, timeZone);
            return(LunarYearTools.jdToDate(monthStart + ld.Day - 1));
        }