// pages/date-calc/date-calc.ts import { solarToLunar, lunarToSolar, getSolarTerm, getFestival, getLunarFestival } from '../../utils/lunar'; Page({ data: { currentTab: 0, startDate: '', startWeekday: '', endDate: '', days: 0, resultDate: '', resultWeekday: '', resultLunar: '', intervalDays: 0, intervalWeeks: 0, intervalRemainingDays: 0, intervalMonths: 0, intervalExtraDays: 0, // 农历转换相关 lunarDirection: 'toL', // 'toL' 公历→农历, 'toS' 农历→公历 lunarSolarDate: '', lunarResult: null as any, lunarFestivalText: '', solarTermText: '', solarFestivalText: '', // 农历→公历 lunarPickerRange: [[] as string[], [] as string[], [] as string[]], lunarPickerValue: [0, 0, 0], lunarPickerDisplay: '', lunarToSolarResult: '', lunarToSolarWeekday: '', // 今日信息 todaySolar: '', todayLunar: '', todayGanZhi: '', todayAnimal: '', todayTerm: '' }, onLoad() { const today = new Date(); const dateStr = this.formatDate(today); this.setData({ startDate: dateStr, endDate: dateStr, resultDate: dateStr, resultWeekday: this.getWeekday(today), startWeekday: this.getWeekday(today), lunarSolarDate: dateStr }); // 初始化农历相关 this.initLunarPicker(); this.updateTodayInfo(); this.convertSolarToLunar(dateStr); this.updateResultLunar(today); }, switchTab(e: any) { wx.vibrateShort({ type: 'light' }).catch(() => {}); this.setData({ currentTab: parseFloat(e.currentTarget.dataset.index) }); this.calculate(); }, bindDateChange(e: any) { const field = e.currentTarget.dataset.field; this.setData({ [field]: e.detail.value }); if (field === 'startDate') { const d = new Date(e.detail.value.replace(/-/g, '/')); this.setData({ startWeekday: this.getWeekday(d) }); } this.calculate(); }, bindDaysInput(e: any) { const val = e.detail.value; if (val === '-' || val === '') { this.setData({ days: val }); return; } this.setData({ days: parseInt(val) }); this.calculate(); }, setDays(e: any) { wx.vibrateShort({ type: 'light' }).catch(() => {}); const days = parseInt(e.currentTarget.dataset.days); this.setData({ days: days }); this.calculate(); }, calculate() { if (this.data.currentTab === 0) { const start = new Date(this.data.startDate.replace(/-/g, '/')); const dayOffset = typeof(this.data.days) === 'number' ? this.data.days : parseInt(this.data.days || '0'); const target = new Date(start.getTime() + dayOffset * 24 * 60 * 60 * 1000); this.setData({ resultDate: this.formatDate(target), resultWeekday: this.getWeekday(target) }); this.updateResultLunar(target); } else if (this.data.currentTab === 1) { const start = new Date(this.data.startDate.replace(/-/g, '/')); const end = new Date(this.data.endDate.replace(/-/g, '/')); const diffTime = Math.abs(end.getTime() - start.getTime()); const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); const weeks = Math.floor(diffDays / 7); const remainingDays = diffDays % 7; const months = Math.floor(diffDays / 30); const extraDays = diffDays % 30; this.setData({ intervalDays: diffDays, intervalWeeks: weeks, intervalRemainingDays: remainingDays, intervalMonths: months, intervalExtraDays: extraDays }); } }, // 更新推算结果的农历信息 updateResultLunar(date: Date) { try { const lunar = solarToLunar(date.getFullYear(), date.getMonth() + 1, date.getDate()); this.setData({ resultLunar: lunar.monthName + lunar.dayName }); } catch (e) { this.setData({ resultLunar: '' }); } }, // === 农历转换相关 === setLunarDirection(e: any) { wx.vibrateShort({ type: 'light' }).catch(() => {}); this.setData({ lunarDirection: e.currentTarget.dataset.dir }); }, toggleLunarDirection() { wx.vibrateShort({ type: 'light' }).catch(() => {}); this.setData({ lunarDirection: this.data.lunarDirection === 'toL' ? 'toS' : 'toL' }); }, onLunarSolarDateChange(e: any) { const dateStr = e.detail.value; this.setData({ lunarSolarDate: dateStr }); this.convertSolarToLunar(dateStr); }, convertSolarToLunar(dateStr: string) { try { const parts = dateStr.split('-'); const year = parseInt(parts[0]); const month = parseInt(parts[1]); const day = parseInt(parts[2]); const result = solarToLunar(year, month, day); const term = getSolarTerm(year, month, day); const solarFest = getFestival(month, day); const lunarFest = getLunarFestival(result.month, result.day); this.setData({ lunarResult: result, solarTermText: term || '', solarFestivalText: solarFest || '', lunarFestivalText: lunarFest || '' }); } catch (e) { console.error('农历转换出错:', e); } }, // 初始化农历选择器 initLunarPicker() { const years: string[] = []; for (let y = 1901; y <= 2099; y++) { years.push(y + '年'); } const months: string[] = []; for (let m = 1; m <= 12; m++) { months.push(this.getLunarMonthLabel(m)); } const days: string[] = []; for (let d = 1; d <= 30; d++) { days.push(this.getLunarDayLabel(d)); } const today = new Date(); // Calculate today's lunar date to set default picker value const result = solarToLunar(today.getFullYear(), today.getMonth() + 1, today.getDate()); const yearIdx = result.year - 1901; const monthIdx = result.month - 1; const dayIdx = result.day - 1; const display = `${result.year}年 ${result.monthName} ${result.dayName}`; this.setData({ lunarPickerRange: [years, months, days], lunarPickerValue: [yearIdx >= 0 ? yearIdx : 0, monthIdx, dayIdx], lunarPickerDisplay: display }); // Also init the reverse calculation result this.calcLunarToSolar(result.year, result.month, result.day); }, getLunarMonthLabel(m: number): string { const names = ['正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月']; return names[m - 1]; }, getLunarDayLabel(d: number): string { const names = [ '初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十' ]; return names[d - 1]; }, onLunarColumnChange(e: any) { // 列变化时可以联动更新(简化处理) }, onLunarPickerChange(e: any) { const val = e.detail.value; const year = 1901 + val[0]; const month = val[1] + 1; const day = val[2] + 1; const display = `${year}年 ${this.getLunarMonthLabel(month)} ${this.getLunarDayLabel(day)}`; this.setData({ lunarPickerValue: val, lunarPickerDisplay: display, }); this.calcLunarToSolar(year, month, day); }, calcLunarToSolar(year: number, month: number, day: number) { try { const result = lunarToSolar(year, month, day, false); const solarDate = new Date(result.year, result.month - 1, result.day); const solarStr = this.formatDate(solarDate); this.setData({ lunarToSolarResult: solarStr, lunarToSolarWeekday: this.getWeekday(solarDate) }); } catch (e) { this.setData({ lunarToSolarResult: '无效日期', lunarToSolarWeekday: '' }); } }, // 今日信息 updateTodayInfo() { const today = new Date(); const y = today.getFullYear(); const m = today.getMonth() + 1; const d = today.getDate(); try { const lunar = solarToLunar(y, m, d); const term = getSolarTerm(y, m, d); this.setData({ todaySolar: `${y}年${m}月${d}日 ${this.getWeekday(today)}`, todayLunar: lunar.monthName + lunar.dayName, todayGanZhi: lunar.ganZhi + '年', todayAnimal: lunar.animal, todayTerm: term || '' }); } catch (e) { console.error('获取今日信息出错:', e); } }, formatDate(date: Date): string { const y = date.getFullYear(); const m = (date.getMonth() + 1).toString().padStart(2, '0'); const d = date.getDate().toString().padStart(2, '0'); return `${y}-${m}-${d}`; }, getWeekday(date: Date): string { const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; return days[date.getDay()]; } })