项目中有一个生日短信提醒功能,需要每年提醒。选农历, 每年提醒, 第二年的公历是不一样的,所以每一年的都需要自己计算。
设计的要求 ,他们说因为年纪大的人是只记得农历的。。。
网上资料不少,公历转农历现成的一堆。都是用微软的System.Globalization.ChineseLunisolarCalendar类写的,
但是农历转公历的很少,也有,但都是只提到方法的调用,比如下面:
正确的应该是1982-10-12 。由于 并没有详细说到关键的闰月计算, 所以起初很困惑,以为计算不准确。
检查全年的月份,发现有因为有闰月的情况,有润月则应该从该闰月起月份自动加一, 如1982年润四月,或则闰五月为6月,后面的月加一处理。
方便理解自己做个对照图:
正确的方法是,要先计算当年农历生日之前的月份有没有闰月,
有了就 直接构造农历日期对象是就把农历的月+1 为9月:
只要明白闰月这一点,其实就很简单了!
/////////// //公历转农历 /////////// DateTime date = Convert.ToDateTime(textBox1.Text); //格式:2000-1-1 ChineseLunisolarCalendar cc = new ChineseLunisolarCalendar(); if (date > cc.MaxSupportedDateTime || date < cc.MinSupportedDateTime) MessageBox.Show("参数日期时间不在支持的范围内,支持范围:"+cc.MinSupportedDateTime.ToShortDateString()+"到"+cc.MaxSupportedDateTime.ToShortDateString()); int year = cc.GetYear(date); int month = cc.GetMonth(date); int dayOfMonth = cc.GetDayOfMonth(date); int leapMonth = cc.GetLeapMonth(year); bool isLeapMonth = cc.IsLeapMonth(year, month); bool isLeapYear = cc.IsLeapYear(year); if (isLeapMonth || isLeapYear && month >= leapMonth) month -= 1; textBox2.Text = string.Concat(year, "-", month, "-", dayOfMonth);
/////////// //农历转公历 /////////// ChineseLunisolarCalendar cc = new ChineseLunisolarCalendar(); DateTime date = Convert.ToDateTime(textBox2.Text); //格式:2000-1-1 int MonthsInYear = cc.GetMonthsInYear(date.Year); int LeapMonth = cc.GetLeapMonth(date.Year, 1); bool isLeapMonth = cc.IsLeapMonth(date.Year, date.Month); bool isLeapYear = cc.IsLeapYear(date.Year); if (isLeapMonth) date = cc.ToDateTime(date.Year, date.Month - 1, date.Day, 0, 0, 0, 0); else if(date.Month > LeapMonth) date = cc.ToDateTime(date.Year, date.Month + 1, date.Day, 0, 0, 0, 0); else date = cc.ToDateTime(date.Year, date.Month, date.Day, 0, 0, 0, 0); textBox1.Text = date.ToString("yyyy-MM-dd");
这是一个WinForm做的的实例Demo: WindowsFormsApplication1