js之阳历 → 农历(含时辰)转换函数

复制代码
使用方法

// 公历:1995年6月15日 8点

var result = solarToLunar(1995, 6, 15, 8);

console.log(result.lunarString);

// 输出:一九九五年五月十八日 08:00-08:59辰时

console.log(result);

// 会返回完整农历对象

复制代码
// ==============================
	// 独立提取:公历转农历(含时辰)
	// 调用示例:solarToLunar(1995, 5, 20, 8)
	// ==============================
	function solarToLunar(year, month, day, hour) {
    var lunarInfo = new Array(
	        0x4bd8, 0x4ae0, 0xa570, 0x54d5, 0xd260, 0xd950, 0x5554, 0x56af, 0x9ad0, 0x55d2, 0x4ae0, 0xa5b6, 0xa4d0, 0xd250, 0xd295, 0xb54f, 0xd6a0, 0xada2, 0x95b0, 0x4977, 0x497f, 0xa4b0, 0xb4b5, 0x6a50, 0x6d40, 0xab54, 0x2b6f, 0x9570, 0x52f2, 0x4970, 0x6566, 0xd4a0, 0xea50, 0x6a95, 0x5adf, 0x2b60, 0x86e3, 0x92ef, 0xc8d7, 0xc95f, 0xd4a0, 0xd8a6, 0xb55f, 0x56a0, 0xa5b4, 0x25df, 0x92d0, 0xd2b2, 0xa950, 0xb557, 0x6ca0, 0xb550, 0x5355, 0x4daf, 0xa5b0, 0x4573, 0x52bf, 0xa9a8, 0xe950, 0x6aa0, 0xaea6, 0xab50, 0x4b60, 0xaae4, 0xa570, 0x5260, 0xf263, 0xd950, 0x5b57, 0x56a0, 0x96d0, 0x4dd5, 0x4ad0, 0xa4d0, 0xd4d4, 0xd250, 0xd558, 0xb540, 0xb6a0, 0x95a6, 0x95bf, 0x49b0, 0xa974, 0xa4b0, 0xb27a, 0x6a50, 0x6d40, 0xaf46, 0xab60, 0x9570, 0x4af5, 0x4970, 0x64b0, 0x74a3, 0xea50, 0x6b58, 0x5ac0, 0xab60, 0x96d5, 0x92e0, 0xc960, 0xd954, 0xd4a0, 0xda50, 0x7552, 0x56a0, 0xabb7, 0x25d0, 0x92d0, 0xcab5, 0xa950, 0xb4a0, 0xbaa4, 0xad50, 0x55d9, 0x4ba0, 0xa5b0, 0x5176, 0x52bf, 0xa930, 0x7954, 0x6aa0, 0xad50, 0x5b52, 0x4b60, 0xa6e6, 0xa4e0, 0xd260, 0xea65, 0xd530, 0x5aa0, 0x76a3, 0x96d0, 0x4afb, 0x4ad0, 0xa4d0, 0xd0b6, 0xd25f, 0xd520, 0xdd45, 0xb5a0, 0x56d0, 0x55b2, 0x49b0, 0xa577, 0xa4b0, 0xaa50, 0xb255, 0x6d2f, 0xada0, 0x4b63, 0x937f, 0x49f8, 0x4970, 0x64b0, 0x68a6, 0xea5f, 0x6b20, 0xa6c4, 0xaaef, 0x92e0, 0xd2e3, 0xc960, 0xd557, 0xd4a0, 0xda50, 0x5d55, 0x56a0, 0xa6d0, 0x55d4, 0x52d0, 0xa9b8, 0xa950, 0xb4a0, 0xb6a6, 0xad50, 0x55a0, 0xaba4, 0xa5b0, 0x52b0, 0xb273, 0x6930, 0x7337, 0x6aa0, 0xad50, 0x4b55, 0x4b6f, 0xa570, 0x54e4, 0xd260, 0xe968, 0xd520, 0xdaa0, 0x6aa6, 0x56df, 0x4ae0, 0xa9d4, 0xa4d0, 0xd150, 0xf252, 0xd520
	    );

var nStr1 = new Array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
var nStr2 = new Array('初', '十', '廿', '卅');
var monthName = new Array("", "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二");

function lYearDays(y) {
    var i, sum = 348;
    for (i = 0x8000; i > 0x8; i >>= 1) sum += (lunarInfo[y - 1900] & i) ? 1 : 0;
    return sum + leapDays(y);
}

function leapDays(y) {
    if (leapMonth(y)) return ((lunarInfo[y - 1899] & 0xf) == 0xf ? 30 : 29);
    else return 0;
}

function leapMonth(y) {
    var lm = lunarInfo[y - 1900] & 0xf;
    return (lm == 0xf ? 0 : lm);
}

function monthDays(y, m) {
    return ((lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);
}

function Lunar(objDate, h) {
    var i, leap = 0, temp = 0;
    var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000;
    if (h > 23) offset++;
    for (i = 1900; i < 2100 && offset > 0; i++) {
        temp = lYearDays(i);
        offset -= temp;
    }
    if (offset < 0) {
        offset += temp;
        i--;
    }
    this.year = i;
    leap = leapMonth(i);
    this.isLeap = false;
    for (i = 1; i < 13 && offset > 0; i++) {
        if (leap > 0 && i == (leap + 1) && !this.isLeap) {
            --i;
            this.isLeap = true;
            temp = leapDays(this.year);
        } else {
            temp = monthDays(this.year, i);
        }
        if (this.isLeap && i == (leap + 1)) this.isLeap = false;
        offset -= temp;
    }
    if (offset == 0 && leap > 0 && i == leap + 1) {
        this.isLeap ? this.isLeap = false : this.isLeap = true; --i;
    }
    if (offset < 0) { offset += temp; --i; }
    this.month = i;
    this.day = offset + 1;
}

function cYear(y) {
    var s = nStr1[Math.floor(y / 1000)];
    s += nStr1[Math.floor((y % 1000) / 100)];
    s += nStr1[Math.floor((y % 100) / 10)];
    s += nStr1[y % 10];
    return s;
}

function cDay(d) {
    switch (d) {
        case 10: return '初十';
        case 20: return '二十';
        case 30: return '三十';
        default: return nStr2[Math.floor(d / 10)] + nStr1[d % 10];
    }
}

// 时辰
var hh = [
    "00:00-00:59早子", "01:00-01:59丑", "02:00-02:59丑",
    "03:00-03:59寅", "04:00-04:59寅", "05:00-05:59卯",
    "06:00-06:59卯", "07:00-07:59辰", "08:00-08:59辰",
    "09:00-09:59巳", "10:00-10:59巳", "11:00-11:59午",
    "12:00-12:59午", "13:00-13:59未", "14:00-14:59未",
    "15:00-15:59申", "16:00-16:59申", "17:00-17:59酉",
    "18:00-18:59酉", "19:00-19:59戌", "20:00-20:59戌",
    "21:00-21:59亥", "22:00-22:59亥", "23:00-23:59晚子"
];

var sDObj = new Date(year, month - 1, day);
var lDObj = new Lunar(sDObj, hour);
var lY = cYear(lDObj.year);
var lM = monthName[lDObj.month];
var lD = cDay(lDObj.day);
var lL = lDObj.isLeap ? '闰' : '';
var lS = (hour >= 0 && hour < 24) ? hh[hour] : '未知';

return {
    lunarString: lY + '年' + lL + lM + '月' + lD + '日 ' + lS + '时',
    lunarYear: lDObj.year,
    lunarMonth: lDObj.month,
    lunarDay: lDObj.day,
    isLeapMonth: lDObj.isLeap,
    hourText: lS
};
}
相关推荐
swipe1 小时前
从 0 到 1 实现大文件上传:分片、秒传、断点续传、暂停、重试与服务端合并
前端·javascript·面试
爱勇宝1 小时前
我做了一个只用来搜歌词的小 App
android·前端·后端
甲维斯1 小时前
用AI还原《坦克大战》并3D化升级!
前端·人工智能·游戏开发
IT_陈寒2 小时前
SpringBoot自动配置坑了我一晚上,原来问题出在这
前端·人工智能·后端
kyriewen2 小时前
AI 生成的代码能跑就行?这 5 个坑迟早炸
前端·javascript·ai编程
kisshyshy3 小时前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
谷子在生长3 小时前
纯血鸿蒙自定义弹窗最佳实践:从「到处复制」到「一行调用」
前端·harmonyos
壹方秘境3 小时前
我用Go语言开发了一个跨平台的HTTPS抓包和调试工具
前端·后端·ios
神秘面具男3 小时前
HarmonyOS 6.0跨端远程控制
前端·后端
枫树下x3 小时前
NestJS基础框架
前端