diff --git a/src/fragmentarium/domain/Date.ts b/src/fragmentarium/domain/Date.ts index 31002b454..186b3a211 100644 --- a/src/fragmentarium/domain/Date.ts +++ b/src/fragmentarium/domain/Date.ts @@ -154,18 +154,20 @@ export class MesopotamianDate { const year = parseInt(this.year.value) const month = parseInt(this.month.value) const day = parseInt(this.day.value) - return this.isSeleucidEra === true - ? this.seleucidToModernDate(year, month, day) - : this.king?.orderGlobal && - Object.values(data.rulerToBrinkmanKings).includes( - this.king?.orderGlobal - ) - ? this.nabonassarEraToModernDate(year, month, day) - : this.isAssyrianDate && this.eponym?.date - ? `ca. ${this.eponym?.date} BCE` - : this.king?.date - ? this.kingToModernDate(year) - : '' + let result = '' + if (this.isSeleucidEra) { + result = this.seleucidToModernDate(year, month, day) + } else if ( + this.king?.orderGlobal && + Object.values(data.rulerToBrinkmanKings).includes(this.king?.orderGlobal) + ) { + result = this.nabonassarEraToModernDate(year, month, day) + } else if (this.isAssyrianDate && this.eponym?.date) { + result = `ca. ${this.eponym?.date} BCE` + } else if (this.king?.date) { + result = this.kingToModernDate(year) + } + return result } private seleucidToModernDate( diff --git a/src/fragmentarium/domain/DateConverter.ts b/src/fragmentarium/domain/DateConverter.ts index 63171560b..491adf6af 100644 --- a/src/fragmentarium/domain/DateConverter.ts +++ b/src/fragmentarium/domain/DateConverter.ts @@ -1,51 +1,9 @@ import data from 'fragmentarium/domain/dateConverterData.json' -import _ from 'lodash' - -interface CalendarProps { - year: number - bcYear?: number - month: number - day: number - weekDay: number - cjdn: number - lunationNabonassar: number - seBabylonianYear: number - seMacedonianYear?: number - seArsacidYear?: number - mesopotamianMonth: number - mesopotamianDay?: number - mesopotamianMonthLength?: number - ruler?: string - regnalYear?: number -} - -interface CalendarUpdateProps { - year: number - month: number - day: number - weekDay: number - cjdn: number - seBabylonianYear: number - lunationNabonassar: number - mesopotamianMonth: number - regnalYear: number - i: number - j: number -} - -export default class DateConverter { - calendar: CalendarProps = { - year: 0, - month: 0, - day: 0, - cjdn: 0, - weekDay: 0, - mesopotamianMonth: 0, - seBabylonianYear: 0, - lunationNabonassar: 0, - } +import DateConverterBase from 'fragmentarium/domain/DateConverterBase' +export default class DateConverter extends DateConverterBase { constructor() { + super() this.setToModernDate(-310, 3, 3) } @@ -127,175 +85,4 @@ export default class DateConverter { ) this.setFromCjdn(cjdn) } - - private setFromCjdn(cjdn: number): void { - const [year, month, day] = this.computeModernDateFromCjnd(cjdn) - this.applyModernDate({ year, month, day }) - this.updateBabylonDate(cjdn) - } - - private computeCjdnFromSeBabylonian( - seBabylonianYear: number, - mesopotamianMonth: number, - mesopotamianDay: number - ): number { - const i = this.findIndexInSeBabylonianYearMonthPeriod([ - seBabylonianYear, - mesopotamianMonth, - ]) - return data.babylonianCjdnPeriod[i] + mesopotamianDay - 1 - } - - private findIndexInSeBabylonianYearMonthPeriod( - yearMonth: [number, number] - ): number { - const i = data.seBabylonianYearMonthPeriod.findIndex((ym) => - _.isEqual(ym, yearMonth) - ) - if (i === -1) - throw new Error('Could not find matching Babylonian date in data.') - return i - } - - private computeModernDateFromCjnd(cjdn: number): [number, number, number] { - const b = cjdn + 1524 - const c = Math.floor((b - 122.1) / 365.25) - const d = Math.floor(365.25 * c) - const e = Math.floor((b - d) / 30.6001) - const day = b - d - Math.floor(30.6001 * e) - const month = e < 14 ? e - 1 : e - 13 - const year = month > 2 ? c - 4716 : c - 4715 - return [year, month, day] - } - - updateBabylonDate( - cjdn: number = this.computeCjdnFromModernDate( - this.calendar.year, - this.calendar.month, - this.calendar.day - ) - ): void { - const weekDay = this.computeWeekDay(cjdn) - const [ - i, - lunationNabonassar, - seBabylonianYear, - mesopotamianMonth, - ] = this.computeBabylonianValues(cjdn) - const [j, regnalYear] = this.computeRegnalValues(seBabylonianYear) - this.updateCalendarProperties({ - year: this.calendar.year, - month: this.calendar.month, - day: this.calendar.day, - cjdn, - weekDay, - lunationNabonassar, - seBabylonianYear, - mesopotamianMonth, - regnalYear, - i, - j, - }) - } - - private computeCjdnFromModernDate( - year: number, - month: number, - day: number - ): number { - return ( - Math.floor(365.25 * (month < 3 ? year - 1 : year + 4716)) + - Math.floor(30.6001 * (month < 3 ? month + 12 : month + 1)) + - day - - 1524 - ) - } - - private computeWeekDay(cjdn: number): number { - return ((cjdn + 1) % 7) + 1 - } - - private computeBabylonianValues( - cjdn: number - ): [number, number, number, number] { - const i = data.babylonianCjdnPeriod.findIndex((cjdnPd) => cjdnPd > cjdn) - const [ - seBabylonianYear, - mesopotamianMonth, - ] = data.seBabylonianYearMonthPeriod[i - 1] - return [i, 1498 + i, seBabylonianYear, mesopotamianMonth] - } - - private computeRegnalValues(seBabylonianYear: number): [number, number] { - const j = data.rulerSeYears.findIndex((year) => year > seBabylonianYear) - return [j, seBabylonianYear - data.rulerSeYears[j - 1] + 1] - } - - private calculateYearOffset(currentMonth: number, offset: number): number { - return currentMonth + offset > 12 ? 1 : currentMonth + offset < 1 ? -1 : 0 - } - - private calculateNewMonth(currentMonth: number, offset: number): number { - return ((currentMonth + offset + 11) % 12) + 1 - } - - updateCalendarProperties(props: CalendarUpdateProps): void { - const { cjdn, weekDay, year, month, day } = props - this.calendar.cjdn = cjdn - this.calendar.weekDay = weekDay - this.applyModernDate({ year, month, day }) - this.applyBabylonianDate(props) - this.applySeleucidDate(props) - } - - private applyModernDate({ - year, - month, - day, - }: Pick): void { - this.calendar = { - ...this.calendar, - year, - month, - day, - bcYear: year < 1 ? 1 - year : undefined, - } - } - - private applyBabylonianDate(props: CalendarUpdateProps): void { - const { cjdn, seBabylonianYear, mesopotamianMonth, i, j } = props - const mesopotamianDay = cjdn - data.babylonianCjdnPeriod[i - 1] + 1 - const mesopotamianMonthLength = - data.babylonianCjdnPeriod[i] - data.babylonianCjdnPeriod[i - 1] - const ruler = seBabylonianYear < 161 ? data.rulerName[j - 1] : undefined - const regnalYear = seBabylonianYear - data.rulerSeYears[j - 1] + 1 - const lunationNabonassar = 1498 + i - this.calendar = { - ...this.calendar, - mesopotamianDay, - mesopotamianMonthLength, - mesopotamianMonth, - ruler, - regnalYear, - lunationNabonassar, - } - } - - private applySeleucidDate(props: CalendarUpdateProps): void { - const { seBabylonianYear, mesopotamianMonth } = props - const seMacedonianYear = - seBabylonianYear > 0 && mesopotamianMonth < 7 - ? seBabylonianYear - : seBabylonianYear > -1 && mesopotamianMonth > 6 - ? seBabylonianYear + 1 - : undefined - const seArsacidYear = - seBabylonianYear >= 65 ? seBabylonianYear - 64 : undefined - this.calendar = { - ...this.calendar, - seBabylonianYear, - seMacedonianYear, - seArsacidYear, - } - } } diff --git a/src/fragmentarium/domain/DateConverterBase.ts b/src/fragmentarium/domain/DateConverterBase.ts new file mode 100644 index 000000000..5b12d1982 --- /dev/null +++ b/src/fragmentarium/domain/DateConverterBase.ts @@ -0,0 +1,218 @@ +import data from 'fragmentarium/domain/dateConverterData.json' +import _ from 'lodash' + +export interface CalendarProps { + year: number + bcYear?: number + month: number + day: number + weekDay: number + cjdn: number + lunationNabonassar: number + seBabylonianYear: number + seMacedonianYear?: number + seArsacidYear?: number + mesopotamianMonth: number + mesopotamianDay?: number + mesopotamianMonthLength?: number + ruler?: string + regnalYear?: number +} + +interface CalendarUpdateProps { + year: number + month: number + day: number + weekDay: number + cjdn: number + seBabylonianYear: number + lunationNabonassar: number + mesopotamianMonth: number + regnalYear: number + i: number + j: number +} + +export default class DateConverterBase { + calendar: CalendarProps = { + year: 0, + month: 0, + day: 0, + cjdn: 0, + weekDay: 0, + mesopotamianMonth: 0, + seBabylonianYear: 0, + lunationNabonassar: 0, + } + + setFromCjdn(cjdn: number): void { + const [year, month, day] = this.computeModernDateFromCjnd(cjdn) + this.applyModernDate({ year, month, day }) + this.updateBabylonDate(cjdn) + } + + applyModernDate({ + year, + month, + day, + }: Pick): void { + this.calendar = { + ...this.calendar, + year, + month, + day, + bcYear: year < 1 ? 1 - year : undefined, + } + } + + computeCjdnFromSeBabylonian( + seBabylonianYear: number, + mesopotamianMonth: number, + mesopotamianDay: number + ): number { + const i = this.findIndexInSeBabylonianYearMonthPeriod([ + seBabylonianYear, + mesopotamianMonth, + ]) + return data.babylonianCjdnPeriod[i] + mesopotamianDay - 1 + } + + calculateYearOffset(currentMonth: number, offset: number): number { + return currentMonth + offset > 12 ? 1 : currentMonth + offset < 1 ? -1 : 0 + } + + calculateNewMonth(currentMonth: number, offset: number): number { + return ((currentMonth + offset + 11) % 12) + 1 + } + + updateBabylonDate( + cjdn: number = this.computeCjdnFromModernDate( + this.calendar.year, + this.calendar.month, + this.calendar.day + ) + ): void { + const weekDay = this.computeWeekDay(cjdn) + const [ + i, + lunationNabonassar, + seBabylonianYear, + mesopotamianMonth, + ] = this.computeBabylonianValues(cjdn) + const [j, regnalYear] = this.computeRegnalValues(seBabylonianYear) + this.updateCalendarProperties({ + year: this.calendar.year, + month: this.calendar.month, + day: this.calendar.day, + cjdn, + weekDay, + lunationNabonassar, + seBabylonianYear, + mesopotamianMonth, + regnalYear, + i, + j, + }) + } + + private findIndexInSeBabylonianYearMonthPeriod( + yearMonth: [number, number] + ): number { + const i = data.seBabylonianYearMonthPeriod.findIndex((ym) => + _.isEqual(ym, yearMonth) + ) + if (i === -1) + throw new Error('Could not find matching Babylonian date in data.') + return i + } + + private computeModernDateFromCjnd(cjdn: number): [number, number, number] { + const b = cjdn + 1524 + const c = Math.floor((b - 122.1) / 365.25) + const d = Math.floor(365.25 * c) + const e = Math.floor((b - d) / 30.6001) + const day = b - d - Math.floor(30.6001 * e) + const month = e < 14 ? e - 1 : e - 13 + const year = month > 2 ? c - 4716 : c - 4715 + return [year, month, day] + } + + private computeCjdnFromModernDate( + year: number, + month: number, + day: number + ): number { + return ( + Math.floor(365.25 * (month < 3 ? year - 1 : year + 4716)) + + Math.floor(30.6001 * (month < 3 ? month + 12 : month + 1)) + + day - + 1524 + ) + } + + private computeWeekDay(cjdn: number): number { + return ((cjdn + 1) % 7) + 1 + } + + private computeBabylonianValues( + cjdn: number + ): [number, number, number, number] { + const i = data.babylonianCjdnPeriod.findIndex((cjdnPd) => cjdnPd > cjdn) + const [ + seBabylonianYear, + mesopotamianMonth, + ] = data.seBabylonianYearMonthPeriod[i - 1] + return [i, 1498 + i, seBabylonianYear, mesopotamianMonth] + } + + private computeRegnalValues(seBabylonianYear: number): [number, number] { + const j = data.rulerSeYears.findIndex((year) => year > seBabylonianYear) + return [j, seBabylonianYear - data.rulerSeYears[j - 1] + 1] + } + + private updateCalendarProperties(props: CalendarUpdateProps): void { + const { cjdn, weekDay, year, month, day } = props + this.calendar.cjdn = cjdn + this.calendar.weekDay = weekDay + this.applyModernDate({ year, month, day }) + this.applyBabylonianDate(props) + this.applySeleucidDate(props) + } + + private applyBabylonianDate(props: CalendarUpdateProps): void { + const { cjdn, seBabylonianYear, mesopotamianMonth, i, j } = props + const mesopotamianDay = cjdn - data.babylonianCjdnPeriod[i - 1] + 1 + const mesopotamianMonthLength = + data.babylonianCjdnPeriod[i] - data.babylonianCjdnPeriod[i - 1] + const ruler = seBabylonianYear < 161 ? data.rulerName[j - 1] : undefined + const regnalYear = seBabylonianYear - data.rulerSeYears[j - 1] + 1 + const lunationNabonassar = 1498 + i + this.calendar = { + ...this.calendar, + mesopotamianDay, + mesopotamianMonthLength, + mesopotamianMonth, + ruler, + regnalYear, + lunationNabonassar, + } + } + + private applySeleucidDate(props: CalendarUpdateProps): void { + const { seBabylonianYear, mesopotamianMonth } = props + const seMacedonianYear = + seBabylonianYear > 0 && mesopotamianMonth < 7 + ? seBabylonianYear + : seBabylonianYear > -1 && mesopotamianMonth > 6 + ? seBabylonianYear + 1 + : undefined + const seArsacidYear = + seBabylonianYear >= 65 ? seBabylonianYear - 64 : undefined + this.calendar = { + ...this.calendar, + seBabylonianYear, + seMacedonianYear, + seArsacidYear, + } + } +}