MySQL:根据阳历获取农历日期函数
2013-11-06 12:44
423 查看
begin DECLARE v_OffSet INT; DECLARE v_Lunar INT; # 农历年是否含闰月,几月是闰月,闰月天数,其它月天数 DECLARE v_YearDays INT; # 农历年所含天数 DECLARE v_MonthDays INT; # 农历月所含天数 DECLARE v_LeapMonthDays INT; # 农历闰月所含天数 DECLARE v_LeapMonth INT; # 农历年闰哪个月 1-12 , 没闰传回 0 DECLARE v_LeapFlag INT; # 某农历月是否为闰月 1:是 0:不是 DECLARE v_MonthNo INT; # 某农历月所对应的2进制数 如农历3月: 001000000000 DECLARE i INT; DECLARE j INT; DECLARE k INT; DECLARE v_Year INT; # i_SolarDay 对应的农历年 DECLARE v_Month INT; # i_SolarDay 对应的农历月 DECLARE v_Day INT; # i_SolarDay 对应的农历日 DECLARE o_OutputDate VARCHAR(25); # 返回值 格式:农历 ****年 **(闰)月 **日 DECLARE e_ErrMsg VARCHAR(200); declare v_j int; declare v_temp_m varchar(100); declare v_temp_d varchar(100); # -e_ErrDate EXCEPTION; #输入参数判断 /* IF i_SolarDay<TO_DATE('1900-01-31','YYYY-MM-DD') OR i_SolarDay>=TO_DATE('2050-01-23','YYYY-MM-DD') THEN RAISE e_ErrDate; END IF ; */ # i_SolarDay 到 1900-01-30(即农历1900-01-01的前一天) 的天数 # v_OffSet := TRUNC(i_SolarDay, 'DD') - TO_DATE('1900-01-30', 'YYYY-MM-DD'); DECLARE exit HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND begin set o_OutputDate ='获取农历失败'; return o_OutputDate; end; set v_OffSet = DATEDIFF(i_SolarDay,str_to_date('1900-01-30', '%Y-%c-%d')); # 确定农历年开始 set i = 1900; WHILE i < 2050 AND v_OffSet > 0 DO set v_YearDays = 348; # 29*12 以每年12个农历月,每个农历月含29个农历日为基数 set v_LeapMonthDays = 0; # 取出农历年是否含闰月,几月是闰月,闰月天数,其它月天数 # 如农历2001年: 0x0d954(16进制) -> 55636(10进制) -> 0 110110010101 0100(2进制) # 1,2,4,5,8,10,12月大, 3,6,7,9,11月小, 4月为闰月,闰月小 SELECT DataInt INTO v_Lunar FROM SolarData WHERE YearId = i; # 传回农历年的总天数 set j = 32768; # 100000000000 0000 -> 32768 # 0 110110010101 0100 -> 55636(农历2001年) # 依次判断v_Lunar年个月是否为大月,是则加一天 WHILE j > 8 Do # 闰月另行判断 8 -> 0 000000000000 1000 set v_j = v_Lunar&j; #IF BITAND(v_Lunar, j) + 0 > 0 then if v_j+0 >0 then set v_YearDays = v_YearDays + 1; #v_YearDays := v_YearDays + 1; END IF; set j = j/2; # 判断下一个月是否为大 END WHILE; # 传回农历年闰哪个月 1-12 , 没闰传回 0 15 -> 1 0000 # v_LeapMonth := BITAND(v_Lunar, 15) + 0; set v_LeapMonth = v_Lunar&15 + 0; # 传回农历年闰月的天数 ,加在年的总天数上 IF v_LeapMonth > 0 THEN # 判断闰月大小 65536 -> 1 000000000000 0000 #IF BITAND(v_Lunar, 65536)+0 > 0 THEN if v_Lunar&65536 + 0 > 0 then set v_LeapMonthDays = 30; ELSE set v_LeapMonthDays = 29; END IF; set v_YearDays = v_YearDays + v_LeapMonthDays; END IF; set v_OffSet = v_OffSet - v_YearDays; set i = i + 1; END WHILE; IF v_OffSet <= 0 THEN # i_SolarDay 在所属农历年(即i年)中的第 v_OffSet 天 set v_OffSet = v_OffSet + v_YearDays; set i = i - 1; END IF; # 确定农历年结束 set v_Year = i; # 确定农历月开始 set i = 1; SELECT DataInt INTO v_Lunar FROM SolarData WHERE YearId = v_Year; # 判断那个月是润月 # 如农历2001年 (55636,15 -> 0 1101100101010100, 1111 -> 4) 即润4月,且闰月小 set v_LeapMonth = v_Lunar&15 + 0; set v_LeapFlag = 0; WHILE i < 13 AND v_OffSet > 0 DO # 判断是否为闰月 set v_MonthDays = 0; IF (v_LeapMonth > 0 AND i = (v_LeapMonth + 1) AND v_LeapFlag = 0) THEN # 是闰月 set i = i - 1; set k = i; # 保存是闰月的时i的值 set v_LeapFlag = 1; # 传回农历年闰月的天数 #IF BITAND(v_Lunar, 65536)+0 > 0 THEN if v_Lunar&65536+0 > 0 then set v_MonthDays = 30; ELSE set v_MonthDays = 29; END IF; ELSE # 不是闰月 set j = 1; set v_MonthNo = 65536; # 计算 i 月对应的2进制数 如农历3月: 001000000000 WHILE j<= i DO set v_MonthNo = v_MonthNo/2; set j = j + 1; END WHILE; # 计算农历 v_Year 年 i 月的天数 #IF BITAND(v_Lunar, v_MonthNo)+0 > 0 THEN if v_Lunar&v_MonthNo + 0 > 0 then set v_MonthDays = 30; ELSE set v_MonthDays = 29; END IF; END IF; # 解除闰月 IF v_LeapFlag = 1 AND i = v_LeapMonth +1 THEN set v_LeapFlag = 0; END IF; set v_OffSet = v_OffSet - v_MonthDays; set i = i + 1; END while; IF v_OffSet <= 0 THEN # i_SolarDay 在所属农历月(即i月)中的第 v_OffSet 天 set v_OffSet = v_OffSet + v_MonthDays; set i = i - 1; END IF; # 确定农历月结束 set v_Month = i; # 确定农历日结束 set v_Day = v_OffSet; # 格式化返回值 set o_OutputDate =CONCAT(getNumYear(v_Year),'年'); IF k = i THEN #set o_OutputDate := o_OutputDate || LPAD(TO_CHAR(v_Month), 2, '0')||'(润)月 '; set v_temp_m = concat(getNumMonth(v_Month),'(润)月 '); ELSE # o_OutputDate := o_OutputDate || LPAD(TO_CHAR(v_Month), 2, '0')||'月 '; set v_temp_m = concat(getNumMonth(v_Month),'月'); END IF; # o_OutputDate := o_OutputDate || LPAD(TO_CHAR(v_Day), 2, '0')||'日'; set v_temp_d = getNumDay(v_Day); set o_OutputDate = CONCAT(CONCAT(o_OutputDate,v_temp_m),v_temp_d); RETURN o_OutputDate; END
相关文章推荐
- MySQL 获取农历日期函数
- 根据经纬度获取两点之间的距离(php&mysql)
- mysql获取外键, 根据数据库名和表名获取表所对应的所有外键
- MySQL 获取农历月份函数
- mysql根据日期获取周一周日
- mysql根据身份证获取省份、生日、性别,存储过程
- mysql根据身份证获取省份、生日、性别,存储过程
- Mysql 实现 Rownum() 排序后根据条件获取名次
- php获取阳历日期的农历类
- MySQL根据某一Date值获取相关时间(前一天,后一天等)
- Mysql 根据URL获取顶级域名
- MySQL根据生日获取年龄
- js 根据年月获取当月有多少天_js获取农历日期_及Js其它常用有用函数
- mysql根据某个字段分组根据更新时间获取最新的记录
- mysql根据身份证信息来获取用户属性信息
- PHP获取农历、阳历转阴历
- Mysql实现Rownum()排序后根据条件获取名次
- mysql 根据昨天日期获取 所有数据、本周数据、本月数据
- php根据二分查找法从普通csv文件中获取ip的地理位置(效率比使用mysql提高近800倍)
- Mysql中根据子表的分组后的最大统计数获取主表中的信息