function calcTimeDiff(startDate, endDate) {
// 輸入:Date 對象或可解析字符串
const start = startDate instanceof Date ? startDate : new Date(startDate);
const end = endDate instanceof Date ? endDate : new Date(endDate);
if (isNaN(start) || isNaN(end)) return null;
let diffMs = end - start; // 毫秒差
if (diffMs < 0) diffMs = -diffMs; // 絕對值
// 精確分解(注意:月/年長度不固定,此處為近似)
const seconds = Math.floor(diffMs / 1000) % 60;
const minutes = Math.floor(diffMs / 60000) % 60;
const hours = Math.floor(diffMs / 3600000) % 24;
const days = Math.floor(diffMs / 86400000);
// 年月近似分解(30天/月,365天/年)
const years = Math.floor(days / 365);
const months = Math.floor((days % 365) / 30);
const remainingDays = days % 365 % 30;
return { years, months, days: remainingDays, hours, minutes, seconds, totalDays: days };
}
// 使用示例
const diff = calcTimeDiff('2024-01-15 10:30:00', '2024-03-20 15:45:30');
console.log(`${diff.years}年 ${diff.months}月 ${diff.days}天 ${diff.hours}時 ${diff.minutes}分 ${diff.seconds}秒`);
// 輸出: 0年 2月 5天 5時 15分 30秒
// 使用 date-fns (需 npm install date-fns)
import { differenceInYears, differenceInMonths, differenceInDays,
differenceInHours, differenceInMinutes, differenceInSeconds } from 'date-fns';
function preciseDiff(start, end) {
const years = differenceInYears(end, start);
const months = differenceInMonths(end, start) % 12;
const days = differenceInDays(end, start) % 30; // 近似
// 更精確需結合具體日曆邏輯
return { years, months, days };
}
純前端實現農曆算法極其複雜(涉及節氣、閏月、冬至點計算),強烈建議**使用成熟庫**:
npm install lunar-javascript,支援 1900-2100 年,API 簡潔import { Lunar, Solar } from 'lunar-javascript';import { Solar, Lunar } from 'lunar-javascript';
// 陽曆轉農曆
const solar = Solar.fromYmd(2024, 3, 20);
const lunar = solar.getLunar();
console.log(lunar.toString()); // 甲辰年二月十一
// 農曆轉陽曆
const lunar2 = Lunar.fromYmd(2024, 2, 11);
const solar2 = lunar2.getSolar();
console.log(solar2.toYmd()); // 2024-03-20
// 同步更新邏輯
function onSolarChange(year, month, day) {
const solar = Solar.fromYmd(year, month, day);
const lunar = solar.getLunar();
updateLunarUI(lunar.getYear(), lunar.getMonth(), lunar.getDay());
}
function onLunarChange(year, month, day) {
const lunar = Lunar.fromYmd(year, month, day);
const solar = lunar.getSolar();
updateSolarUI(solar.getYear(), solar.getMonth(), solar.getDay());
}
// 簡化版:僅演示結構,實際需幾百行算法
const LunarData = {
// 1900-2100 年每年天數、閏月信息編碼...
};
function solarToLunar(year, month, day) {
// 1. 計算距離基準日(如 1900-01-31)的天數
// 2. 查表找到農曆年、是否閏月、月份天數
// 3. 逐月減去天數定位月份、日期
// 極其繁瑣,生產環境禁用
return { year: 0, month: 0, day: 0, leap: false };
}
<select id="sYear" onchange="syncLunar()"></select>年
<select id="sMonth" onchange="syncLunar()"></select>月
<select id="sDay" onchange="syncLunar()"></select>日
<select id="lYear"></select>年
<select id="lMonth"></select>月
<select id="lDay"></select>日
<script type="module">
import { Solar, Lunar } from 'https://cdn.jsdelivr.net/npm/lunar-javascript@latest/dist/lunar.esm.js';
function initSelects() {
// 初始化陽曆下拉框 1900-2100
for (let y = 1900; y <= 2100; y++) addOption('sYear', y);
for (let m = 1; m <= 12; m++) addOption('sMonth', m);
updateDays('sYear', 'sMonth', 'sDay');
// 初始化農曆下拉框(動態根據年份)
updateLunarSelects(2024);
}
function syncLunar() {
const y = +document.getElementById('sYear').value;
const m = +document.getElementById('sMonth').value;
const d = +document.getElementById('sDay').value;
const lunar = Solar.fromYmd(y, m, d).getLunar();
setSelect('lYear', lunar.getYear());
setSelect('lMonth', lunar.getMonth());
setSelect('lDay', lunar.getDay());
}
function addOption(id, val) { /* ... */ }
function updateDays(sY, sM, sD) { /* 根據年月更新天數下拉 */ }
function setSelect(id, val) { /* 設置下拉框值 */ }
</script>
時間差計算用 Date.getTime() 毫秒差分解;農曆同步**必須用成熟庫**(lunar-javascript),自寫算法工程量大且易錯。下拉框聯動核心:onchange → Solar/Lunar 轉換 → 更新另一組下拉框。時分秒若無實際時間輸入,差值恆為 0。