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>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user