internal void GregorianToLunar(int nSYear, int nSMonth, int nSDate, ref int nLYear, ref int nLMonth, ref int nLDate) {
// unsigned int nLYear, nLMonth, nLDate; // lunar ymd
int nSolarDay; // day # in solar year
int nLunarDay; // day # in lunar year
int fLeap; // is it a solar leap year?
int LDpM; // lunar days/month bitfield
int mask; // mask for extracting bits
int nDays; // # days this lunar month
int nJan1Month, nJan1Date;
// calc the solar day of year
fLeap = GergIsleap(nSYear);
nSolarDay = (fLeap==1) ? DaysToMonth366[nSMonth-1]: DaysToMonth365[nSMonth-1] ;
nSolarDay += nSDate;
// init lunar year info
nLunarDay = nSolarDay;
nLYear = nSYear;
if (nLYear == (MaxCalendarYear + 1)) {
nLYear--;
nLunarDay += ((GergIsleap(nLYear)==1) ? 366 : 365);
nJan1Month = GetYearInfo(nLYear, Jan1Month);
nJan1Date = GetYearInfo(nLYear,Jan1Date);
} else {
nJan1Month = GetYearInfo(nLYear, Jan1Month);
nJan1Date = GetYearInfo(nLYear,Jan1Date);
// check if this solar date is actually part of the previous
// lunar year
if ((nSMonth < nJan1Month) ||
(nSMonth == nJan1Month && nSDate < nJan1Date)) {
// the corresponding lunar day is actually part of the previous
// lunar year
nLYear--;
// add a solar year to the lunar day #
nLunarDay += ((GergIsleap(nLYear)==1) ? 366 : 365);
// update the new start of year
nJan1Month = GetYearInfo(nLYear, Jan1Month);
nJan1Date = GetYearInfo(nLYear, Jan1Date);
}
}
// convert solar day into lunar day.
// subtract off the beginning part of the solar year which is not
// part of the lunar year. since this part is always in Jan or Feb,
// we don't need to handle Leap Year (LY only affects March
// and later).
nLunarDay -= DaysToMonth365[nJan1Month-1];
nLunarDay -= (nJan1Date - 1);
// convert the lunar day into a lunar month/date
mask = 0x8000;
LDpM = GetYearInfo(nLYear, nDaysPerMonth);
nDays = ((LDpM & mask) != 0) ? 30 : 29;
nLMonth = 1;
while (nLunarDay > nDays) {
nLunarDay -= nDays;
nLMonth++;
mask >>= 1;
nDays = ((LDpM & mask) != 0) ? 30 : 29;
}
nLDate = nLunarDay;
}