做网站[url]http://www.cshbl.com[/url]时想在首页显示一个日历,包含农历的,google了很多次,都没有找到ruby版本的类,后来自己根据网络上java农历转换程序的算法,制作了一个ruby版本的。可以把一个阳历日期,转换成农历。
现在共享出来,供有同样需求的兄弟姐妹使用。
小的初学ruby,可能有写的不恰当,不优雅支出,烦请诸位不吝笔墨,指正一二。

用法:

[code] 

nongli = NongLi.new(Date.today) 

print nongli.year + "[" + nongli.shengxiao + "]年\n" 

print nongli.month + nongli.day + "\n" 

print nongli.holidays 

[/code] 


(可以从附件中下载,解压即可) 

源码: 

[code]class NongLi 


 @@lunarInfo = [0x04bd8, 0x04ae0, 0x0a570, 

 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 

 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 

 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 

 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 

 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 

 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 

 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 

 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 

 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 

 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 

 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 

 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 

 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 

 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 

 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 

 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 

 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 

 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 

 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 

 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 

 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 ] 


 @@year20 = [1, 4, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1 ] 

 @@year19 = [ 0, 3, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0 ] 

 @@year2000 = [0, 3, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1 ] 

 @@nStr1 = ["","正","二","三","四","五","六","七","八","九","十","十一","十二"] 


 @@gan= ["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"] 

 @@zhi= ["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"] 

 @@shuxiang = ["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"] 

 @@holiday = [ 

 ["0101", "元旦", 1], 

 ["0214", "情人节", 0], 

 ["0308", "妇女节", 0], 

 ["0312", "植树节", 0], 

 ["0315", "消费者权益日", 0], 

 ["0401", "愚人节", 0], 

 ["0501", "劳动节", 1], 

 ["0504", "青年节", 0], 

 ["0512", "护士节", 0], 

 ["0601", "儿童节", 0], 

 ["0808", "父亲节", 0], 

 ["0910", "教师节", 0], 

 ["0928", "孔子诞辰", 0], 

 ["1001", "国庆节", 1], 

 ["1006", "老人节", 0], 

 ["1024", "联合国日", 0], 

 ["1112", "孙中山诞辰", 0], 

 ["1225", "圣诞节", 0]] 

 @@nongli_holiday = [ 

 ["0101", "春节", 1], 

 ["0115", "元宵节", 0], 

 ["0505", "端午节", 0], 

 ["0707", "七夕情人节", 0], 

 ["0815", "中秋节", 0], 

 ["0909", "重阳节", 0], 

 ["1208", "腊八节", 0], 

 ["0100", "除夕", 1]] 

 @@date = Date.today 

 @@nongli_year = "" 

 @@nongli_month = 0 

 @@nongli_day = 0 

 @@nongli_run = 0 

 #传出y年m月d日对应的农历.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6 


 def initialize(d = Date.today) 

 @@date = d 

 year = @@date.year 

 month = @@date.month 

 date = @@date.day 

 l = calElement(year, month, date) 

 @@nongli_year = l[0] 

 @@nongli_month = l[1] 

 @@nongli_day = l[2] 

 @@nongli_run = l[6] 

 end 


 #农历 年份 

 def year 

 return cyclical(@@nongli_year) 

 end 


 #农历月份 

 def month 

 return (@@nongli_run == 1 ? "闰" : "") + @@nStr1[@@nongli_month] + "月" 

 end 


 #农历日 

 def day 

 return getChinaDate(@@nongli_day) 

 end 


 #返回节日,如果有多个节日,逗号分割 

 def holidays 

 names = "" 

 #查询公历节日 

 md = "" 

 if(@@date.month < 10) 

 md = "0" + @@date.month.to_s() 

 else 

 md = @@date.month.to_s() 

 end 

 if(@@date.day < 10) 

 md += "0" + @@date.day.to_s() 

 else 

 md += @@date.day.to_s() 

 end 

 for h in @@holiday 

 if(h[0] == md) 

 names += h[1] + " " 

 end 

 end 


 #查询农历节日 

 md = "" 

 if(@@nongli_month.to_i() < 10) 

 md = "0" + @@nongli_month.to_s() 

 else 

 md = @@nongli_month.to_s() 

 end 

 if(@@nongli_day.to_i() < 10) 

 md += "0" + @@nongli_day.to_s() 

 else 

 md += @@nongli_day.to_s() 

 end 

 for h in @@nongli_holiday 

 if(h[0] == md) 

 names += h[1] + " " 

 end 

 end 



 return names 

 end 


 #查询是否需要变红的重大节日 0,不是; 1,是 

 def isImportantHoliday 

 #查询公历节日 

 md = "" 

 if(@@date.month < 10) 

 md = "0" + @@date.month.to_s() 

 else 

 md = @@date.month.to_s() 

 end 

 if(@@date.day < 10) 

 md += "0" + @@date.day.to_s() 

 else 

 md += @@date.day.to_s() 

 end 

 for h in @@holiday 

 if(h[0] == md && h[2] == 1) 

 return 1 

 end 

 end 


 #查询农历节日 

 md = "" 

 if(@@nongli_month.to_i() < 10) 

 md = "0" + @@nongli_month.to_s() 

 else 

 md = @@nongli_month.to_s() 

 end 

 if(@@nongli_day.to_i() < 10) 

 md += "0" + @@nongli_day.to_s() 

 else 

 md += @@nongli_day.to_s() 

 end 

 for h in @@nongli_holiday 

 if(h[0] == md && h[2] == 1) 

 end 

 end 

 return 0 

 end 


 #返回生肖 

 def shengxiao 

 return shengxiaoYear(@@nongli_year) 

 end 


 def to_s 

 year = @@date.year 

 month = @@date.month 

 date = @@date.day 

 l = calElement(year, month, date) 

 sDay = year.to_s() + "/" + month.to_s() + "/" + date.to_s() + " (" + l[0].to_s() + "-" + l[1].to_s() + "-" + l[2].to_s() + "-" + l[3].to_s() + "-" + l[4].to_s() + "-" + l[5].to_s() + "-" + l[6].to_s() + ")" 

 sDay += "农历 " + cyclical(@@nongli_year) 

 sDay += "年(" + shengxiaoYear(@@nongli_year) + ") " 

 sDay += @@nongli_run == 1 ? "闰" : "" 

 sDay += @@nStr1[@@nongli_month] + "月" 

 sDay += getChinaDate(@@nongli_day) 

 return sDay 

 end 


 #传回农历 y年的总天数 

 def lYearDays(y) 

 sum = 348 

 i = 0x8000 

 while i > 0x8 

 if ((@@lunarInfo[y - 1900] & i) != 0) 

 sum += 1 

 end 

 i >>= 1 

 end 

 return (sum + leapDays(y)) 

 end 


 #传回农历 y年闰月的天数 

 def leapDays(y) 

 if (leapMonth(y) != 0) 

 if ((@@lunarInfo[y - 1900] & 0x10000) != 0) 

 return 30 

 else 

 return 29 

 end 

 else 

 return 0 

 end 

 end 


 #传回农历 y年闰哪个月 1-12 , 没闰传回 0 

 def leapMonth(y) 

 return (@@lunarInfo[y - 1900] & 0xf) 

 end 



 #传回农历 y年m月的总天数 

 def monthDays(y, m) 

 if ((@@lunarInfo[y - 1900] & (0x10000 >> m)) == 0) 

 return 29 

 else 

 return 30 

 end 

 end 


 #传回农历 y年的生肖 

 def shengxiaoYear(y) 

 return @@shuxiang[(y - 4) % 12] 

 end 


 #传入 月日的offset 传回干支,0=甲子 

 def cyclicalm(num) 

 return (@@gan[num % 10] + @@zhi[num % 12]) 

 end 


 #传入 offset 传回干支, 0=甲子 

 def cyclical(y) 

 num = y - 1900 + 36 

 return (cyclicalm(num)) 

 end 


 #传出农历.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6 

 def Lunar(y, m) 

 #long[] nongDate = new long[7]; 

 nongDate = [] 

 i = 0 

 temp = 0 

 leap = 0 

 baseDate = Date.new(1900+1900, 1, 31) 

 objDate = Date.new(y+1900, m, 1); 

 offset = objDate - baseDate 

 if (y < 2000) 

 offset += @@year19[m - 1] 

 elsif (y > 2000) 

 offset += @@year20[m - 1] 

 elsif (y == 2000) 

 offset += @@year2000[m - 1] 

 end 


 nongDate[5] = offset + 40 

 nongDate[4] = 14 


 i = 1900 

 while (i < 2050 && offset > 0) 

 temp = lYearDays(i) 

 offset -= temp 

 nongDate[4] += 12 


 i += 1 

 end 

 if (offset < 0) 

 offset += temp 

 i -= 1 

 nongDate[4] -= 12 

 end 

 nongDate[0] = i 

 nongDate[3] = i - 1864 

 leap = leapMonth(i) # 闰哪个月 

 nongDate[6] = 0 


 i=1 

 while(i<13 && offset > 0) 

 #闰月 

 if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) 

 i -= 1 

 nongDate[6] = 1 

 temp = leapDays( nongDate[0]) 

 else 

 temp = monthDays( nongDate[0], i) 

 end 


 #解除闰月 

 if (nongDate[6] == 1 && i == (leap + 1)) 

 nongDate[6] = 0 

 end 

 offset -= temp; 

 if (nongDate[6] == 0 ) 

 nongDate[4] += 1 

 end 



 i += 1 

 end 


 if (offset == 0 && leap > 0 && i == leap + 1) 

 if (nongDate[6] == 1) 

 nongDate[6] = 0 

 else 

 nongDate[6] = 1 

 i -= 1 

 nongDate[4] -= 1 

 end 

 end 

 if (offset < 0) 

 offset += temp 

 i -= 1 

 nongDate[4] -= 1 

 end 

 nongDate[1] = i 

 nongDate[2] = offset + 1 


 return nongDate 

 end 



 #传出y年m月d日对应的农历.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6 

 def calElement(y, m, d) 

 nongDate = [] 

 i = 0 

 temp = 0 

 leap = 0 

 baseDate = Date.new(0+1900, 1, 31) 


 objDate = Date.new(y, m, d); 

 offset = objDate - baseDate 

 nongDate[5] = offset + 40; 

 nongDate[4] = 14; 


 i = 1900 

 while (i < 2050 && offset > 0) 

 temp = lYearDays(i) 

 offset -= temp 

 nongDate[4] += 12 


 i += 1 

 end 


 if (offset < 0) 

 offset += temp 

 i -= 1 

 nongDate[4] -= 12 

 end 

 nongDate[0] = i 

 nongDate[3] = i - 1864 

 leap = leapMonth(i) #闰哪个月 

 nongDate[6] = 0 


 i = 1 

 while(i<13 && offset > 0) 

 #闰月 

 if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) 

 i -= 1 

 nongDate[6] = 1 

 temp = leapDays( nongDate[0]) 

 else 

 temp = monthDays( nongDate[0], i) 

 end 


 #解除闰月 

 if (nongDate[6] == 1 && i == (leap + 1)) 

 nongDate[6] = 0 

 end 

 offset -= temp 

 if (nongDate[6] == 0) 

 nongDate[4] += 1 

 end 


 i += 1 

 end 


 if (offset == 0 && leap > 0 && i == leap + 1) 

 if (nongDate[6] == 1) 

 nongDate[6] = 0 

 else 

 nongDate[6] = 1 

 i -= 1 

 nongDate[4] -= 1 

 end 

 end 

 if (offset < 0) 

 offset += temp 

 i -= 1 

 nongDate[4] -= 1 

 end 

 nongDate[1] = i 

 nongDate[2] = offset + 1 


 return nongDate 

 end 


 def getChinaDate(day) 

 a = "" 

 if (day == 10) 

 return "初十" 

 elsif (day==20) 

 return "二十" 

 elsif (day==30) 

 return "三十" 

 end 


 two = ((day) / 10).to_i() 


 if (two == 0) 

 a = "初" 

 elsif (two == 1) 

 a = "十" 

 elsif (two == 2) 

 a = "廿" 

 elsif (two == 3) 

 a = "三" 

 else 

 a = "ERROR" 

 end 

 one = (day % 10) 


 case one 

 when 1 then a += "一" 

 when 2 then a += "二" 

 when 3 then a += "三" 

 when 4 then a += "四" 

 when 5 then a += "五" 

 when 6 then a += "六" 

 when 7 then a += "七" 

 when 8 then a += "八" 

 when 9 then a += "九" 

 end 


 return a 

 end 



 #sample计算今天 

 def today 

 today = Date.today 

 year = today.year 

 month = today.month 

 date = today.date 

 l = calElement(year, month, date) 

 sToday = year.to_s() + "/" + month.to_s() + "/" + date.to_s() + " " 

 sToday += "农历 " + cyclical(l[0]) + "(" + shengxiaoYear(l[0]) + ")年 " + @@nStr1[l[1]] + "月" + getChinaDate(l[2]) 

 return sToday 

 end 

end 


[/code]


没有做24节气的显示,如果谁知道哪有做了的,请告诉我。
isImportantHoliday 是我用来控制显示时是否要显示成红色的节日
在节日的数组最后一位进行设置