Files
dekun abf78cbbb5 Use lunar calendar input for birth date with solar conversion display.
Add LunarBirthPicker for bazi and combined forms, converting lunar input to solar for chart calculation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 09:06:37 +08:00

80 lines
2.0 KiB
TypeScript

import { Lunar, Solar } from "lunar-javascript";
export interface LunarDateParts {
year: number;
month: number;
day: number;
isLeapMonth: boolean;
}
/** 农历 → 阳历 YYYY-MM-DD,无效则 null */
export function lunarToSolarYmd(parts: LunarDateParts): string | null {
try {
const month = parts.isLeapMonth ? -parts.month : parts.month;
const lunar = Lunar.fromYmd(parts.year, month, parts.day);
return lunar.getSolar().toYmd();
} catch {
return null;
}
}
/** 阳历 YYYY-MM-DD → 农历分量 */
export function solarYmdToLunarParts(ymd: string): LunarDateParts | null {
try {
const [y, m, d] = ymd.split("-").map(Number);
if (!y || !m || !d) {
return null;
}
const lunar = Solar.fromYmd(y, m, d).getLunar();
const month = lunar.getMonth();
return {
year: lunar.getYear(),
month: Math.abs(month),
day: lunar.getDay(),
isLeapMonth: month < 0,
};
} catch {
return null;
}
}
/** 格式化农历显示 */
export function formatLunarLabel(parts: LunarDateParts): string | null {
try {
const month = parts.isLeapMonth ? -parts.month : parts.month;
return Lunar.fromYmd(parts.year, month, parts.day).toString();
} catch {
return null;
}
}
/** 格式化阳历显示 */
export function formatSolarLabel(ymd: string): string | null {
try {
const [y, m, d] = ymd.split("-").map(Number);
if (!y || !m || !d) {
return null;
}
const solar = Solar.fromYmd(y, m, d);
const week = ["日", "一", "二", "三", "四", "五", "六"][solar.getWeek()];
return `${y}${m}${d}日 星期${week}`;
} catch {
return null;
}
}
export function todayLunarParts(): LunarDateParts {
const lunar = Solar.fromDate(new Date()).getLunar();
const month = lunar.getMonth();
return {
year: lunar.getYear(),
month: Math.abs(month),
day: lunar.getDay(),
isLeapMonth: month < 0,
};
}
export function todaySolarYmd(): string {
return Solar.fromDate(new Date()).toYmd();
}