<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
?<head>
? <title>公歷轉換農歷日期的代碼</title>
? <script language="javascript">
<!--
// 數組LunarDaysOfMonth存入農歷2001年到2050年每年中的月天數信息
// 農歷每月只能是29或30天,一年用12(或13)個二進制位表示,從高到低,對應位為1表示30天,否則29天
var LunarDaysOfMonth = new Array
(
??? 0xd4a8, 0xd4a0, 0xda50, 0x5aa8, 0x56a0, 0xaad8, 0x25d0, 0x92d0, 0xc958, 0xa950, // 2001-2010
??? 0xb4a0, 0xb550, 0xb550, 0x55a8, 0x4ba0, 0xa5b0, 0x52b8, 0x52b0, 0xa930, 0x74a8, // 2011-2020
??? 0x6aa0, 0xad50, 0x4da8, 0x4b60, 0x9570, 0xa4e0, 0xd260, 0xe930, 0xd530, 0x5aa0, // 2021-2030
??? 0x6b50, 0x96d0, 0x4ae8, 0x4ad0, 0xa4d0, 0xd258, 0xd250, 0xd520, 0xdaa0, 0xb5a0, // 2031-2040
??? 0x56d0, 0x4ad8, 0x49b0, 0xa4b8, 0xa4b0, 0xaa50, 0xb528, 0x6d20, 0xada0, 0x55b0? // 2041-2050
);
?
// 數組LunarLeapYear存放農歷2001年到2050年閏月的月份,如沒有則為0,從高到低,每字節存兩年
var LunarLeapYear = new Array
(
??? 0x40, 0x02, 0x07, 0x00, 0x50, // 2001-2010
??? 0x04, 0x09, 0x00, 0x60, 0x04, // 2011-2020
??? 0x00, 0x20, 0x60, 0x05, 0x00, // 2021-2030
??? 0x30, 0xb0, 0x06, 0x00, 0x50, // 2031-2040
??? 0x02, 0x07, 0x00, 0x50, 0x03? // 2041-2050
);
?
?
// 返回農歷iLunarYear年的閏月月份,如沒有則返回0
function GetLeapMonth(iLunarYear)
{
??? var Leap = LunarLeapYear[(iLunarYear - 2001) >> 1];
??? return (((iLunarYear - 2001) & 1) == 0) ? (Leap >> 4) : (Leap & 0x0f);
}
?
// 返回農歷iLunarYer年iLunarMonth月的天數,結果是一個長整數
// 如果iLunarMonth不是閏月, 高字為0,低字為該月的天數
// 如果iLunarMonth是閏月, 高字為后一個月的天數,低字為前一個月的天數
function LunarMonthDays(iLunarYear, iLunarMonth)
{
??? var High;
??? var Low;
??? var Bit;
?
??? High = 0;
??? Low = 29;
??? Bit = 16 - iLunarMonth;
??? if ((iLunarMonth > GetLeapMonth(iLunarYear)) && (GetLeapMonth(iLunarYear) > 0))? Bit--;
??? if ((LunarDaysOfMonth[iLunarYear - 2001] & (1 << Bit)) > 0)? Low++;
??? if (iLunarMonth == GetLeapMonth(iLunarYear))
??? {
??????? High = ((LunarDaysOfMonth[iLunarYear - 2001] & (1 << (Bit-1))) > 0) ?? 30 : 29;
??? }
?
??? return Low + (High << 16);
}
?
// 返回農歷iLunarYear年的總天數
function LunarYearDays(iLunarYear)
{
??? var Days;
??? var tmp;
?
??? Days = 0;
??? for (var i=1; i <= 12; i++)
??? {
??????? tmp = LunarMonthDays(iLunarYear, i);
??????? Days = Days + ((tmp >> 16) & 0xffff); //取高位
??????? Days = Days + (tmp & 0xffff); //取低位
??? }
?
??? return Days;
}
?
// 將農歷iLunarYear年格式化成天干地支記年法表示的字符串
function FormatLunarYear(iLunarYear)
{
??? var szText1 = new String("甲乙丙丁戊己庚辛壬癸");
??? var szText2 = new String("子丑寅卯辰巳午未申酉戌亥");
??? var strYear;
?
??? strYear = szText1.substr((iLunarYear - 4) % 10, 1);
??? strYear = strYear + szText2.substr((iLunarYear - 4) % 12, 1);
?
??? return strYear + "年";
}
?
// 將農歷iLunarMonth月格式化成農歷表示的字符串
function FormatLunarMonth(iLunarMonth)
{
??? var szText = new String("正二三四五六七八九十");
??? var strMonth;
?
??? if (iLunarMonth <= 10)
??? {
??????? strMonth = szText.substr(iLunarMonth - 1, 1);
??? }
??? else if (iLunarMonth == 11) strMonth = "十一";
??? else strMonth = "十二";
?
??? return strMonth + "月";
}
?
// 將農歷iLunarDay日格式化成農歷表示的字符串
function FormatLunarDay(iLunarDay)
{
??? var szText1 = new String("初十廿三");
??? var szText2 = new String("一二三四五六七八九十");
??? var strDay;
??? if ((iLunarDay != 20) && (iLunarDay != 30))
??? {
??????? strDay = szText1.substr((iLunarDay - 1) / 10, 1) + szText2.substr((iLunarDay - 1) % 10, 1);
??? }
??? else if (iLunarDay != 20)
??? {
??????? strDay = szText1.substr(iLunarDay / 10, 1) + "十";
??? }
??? else
??? {
??????? strDay = "二十";
??? }
?
??? return strDay;
}
?
// 將公歷日期轉換為農歷日期,返回農歷表示的字符串
function GetLunarDateString(SolarDate)
{
??? var tmp;
??? var iLunarYear;
??? var iLunarMonth;
??? var iLunarDay;
??? var Leap = false;
??? var MinMilli = 1000 * 60;
??? var HrMilli = MinMilli * 60;
??? var DyMilli = HrMilli * 24;
?
??? // 從2001年1月1日算起,給定的公歷日期已經過去的天數
??? // 11323是1970年1月1日到2001年1月1日之間的天數,因為Date是從1970年1月1日作為起點的
??? var iSpanDays = Math.round(SolarDate.getTime() / DyMilli) - 11323;
?
??? // 公歷2001年1月24日為農歷2001年正月初一,差23天
??? if (iSpanDays < 23)
??? {
??????? iYear = 2000;
??????? iLunarMonth = 12;
??????? iLunarDay = iSpanDays + 7;
??? }
??? else
??? {
??????? // 從農歷2001年正月初一算起
??????? iSpanDays = iSpanDays - 23;
??????? iLunarYear = 2001;
??????? iLunarMonth = 1;
??????? iLunarDay = 1;
?
??????? // 計算農歷年
??????? tmp = LunarYearDays(iLunarYear);
??????? while (iSpanDays >= tmp)
??????? {
??????????? iSpanDays -= tmp;
??????????? iLunarYear++;
??????????? tmp = LunarYearDays(iLunarYear);
??????? }
?
??????? // 計算農歷月
??????? tmp = LunarMonthDays(iLunarYear, iLunarMonth) & 0xffff; //取低字
??????? while (iSpanDays >= tmp)
??????? {
??????????? iSpanDays -= tmp;
??????????? if (iLunarMonth == GetLeapMonth(iLunarYear))? // 該年該月閏月
??????????? {
??????????????? tmp = LunarMonthDays(iLunarYear, iLunarMonth) >> 16; //取高字
??????????????? if (iSpanDays < tmp)
??????????????? {
??????????????????? Leap = (tmp > 0) ? true : false;? // 閏月的后個月?
??????????????????? break;
??????????????? }
??????????????? iSpanDays = iSpanDays - tmp;
??????????? }
?
??????????? iLunarMonth++;
??????????? tmp = LunarMonthDays(iLunarYear,iLunarMonth) & 0xffff; //取低字
??????? }
?
??????? // 計算農歷日
??????? iLunarDay += iSpanDays;
??? }
?
??? return FormatLunarYear(iLunarYear) + (Leap ? "閏" : "") + FormatLunarMonth(iLunarMonth) + FormatLunarDay(iLunarDay);
}
//-->
</script>
?</head>
?<body>
?<script type="text/javascript">
// 也可以指定日期 var today= new Date(2006, 5, 18);
var today= new Date(); // 今天日期
var str = GetLunarDateString(today);
document.write("今天是:"+str+"")
</script>
?</body>
</html>