fortel-ziweidoushu
Version:
紫微斗數排盤 Zi Wei Dou Shu
137 lines (123 loc) • 4.48 kB
text/typescript
import { DayTimeGround } from '../model/dayTimeGround'
import { ConfigType, DestinyConfig, Gender } from '../model/destinyConfig'
import { defaultCalendar } from '../calendar/defaultCalendar'
import { Calendar, CalendarType } from '../calendar/calender'
import { destinyConfigTextParser } from './destinyConfigTextParser'
export class DestinyConfigBuilder {
static withSolar(params: {
year: number
month: number
day: number
bornTimeHour?: number
bornTimeGround?: DayTimeGround
configType: ConfigType
gender: Gender
calendar?: Calendar
}) {
const { year, month, day, bornTimeHour, configType = ConfigType.SKY, gender } = params
let { bornTimeGround, calendar } = params
calendar ??= defaultCalendar
const lunarDate = calendar.solar2lunar(year, month, day)
const { yearSky, yearGround, monthSky, monthGround, daySky, dayGround } = lunarDate
if (bornTimeHour !== undefined) {
bornTimeGround = DayTimeGround.getByHour(bornTimeHour)
} else if (bornTimeGround === undefined) {
throw new Error('Cannot find born time ground')
}
return new DestinyConfig({
year: lunarDate.lunarYear,
month: lunarDate.lunarMonth,
day: lunarDate.lunarDay,
isLeapMonth: lunarDate.isLeapMonth,
yearSky,
yearGround,
monthSky,
monthGround,
daySky,
dayGround,
bornTimeGround,
configType,
gender,
})
}
static withlunar(params: {
year: number
month: number
day: number
isLeapMonth?: boolean
bornTimeHour?: number
bornTimeGround?: DayTimeGround
configType: ConfigType
gender: Gender
calendar?: Calendar
}) {
const { year, month, day, isLeapMonth = false, bornTimeHour, configType = ConfigType.SKY, gender } = params
let { bornTimeGround, calendar } = params
calendar ??= defaultCalendar
const calendarResult = calendar.lunarSkyGround(year, month, day, isLeapMonth)
const { yearSky, yearGround, monthSky, monthGround, daySky, dayGround } = calendarResult
if (bornTimeHour !== undefined && !bornTimeGround) {
bornTimeGround = DayTimeGround.getByHour(bornTimeHour)
}
if (bornTimeGround === undefined) {
throw new Error('Cannot find born time ground')
}
return new DestinyConfig({
year,
month,
day,
isLeapMonth,
yearSky,
yearGround,
monthSky,
monthGround,
daySky,
dayGround,
bornTimeGround,
configType,
gender,
})
}
static withText(input: string, calendar: Calendar = defaultCalendar) {
input = input.trim().replaceAll('/s+', ' ')
const parseResult = destinyConfigTextParser.parse(input, calendar)
const { year, month, day, isLeapMonth, bornTimeGround, hour } = parseResult
let { calendarType, gender, configType } = parseResult
if (calendarType === null) {
calendarType = CalendarType.LUNAR
}
if (gender === null) {
gender = Gender.M
}
if (configType === null) {
configType = ConfigType.SKY
}
if (!year || !month || !day || !bornTimeGround) {
throw new Error('Invalid input')
}
if (calendarType === CalendarType.LUNAR) {
return DestinyConfigBuilder.withlunar({
year,
month,
day,
isLeapMonth,
bornTimeHour: hour ?? undefined,
bornTimeGround: bornTimeGround ?? undefined,
configType,
gender,
calendar,
})
} else {
return DestinyConfigBuilder.withSolar({
year,
month,
day,
bornTimeHour: hour ?? undefined,
bornTimeGround: bornTimeGround ?? undefined,
configType,
gender,
calendar,
})
}
}
}