Skip to content

Commit

Permalink
Modern date display (#393)
Browse files Browse the repository at this point in the history
* Implement date converter

* Refactor

* Refactor more

* Add tests
  • Loading branch information
khoidt authored Sep 22, 2023
1 parent 5c2bbf7 commit 4b8347f
Show file tree
Hide file tree
Showing 8 changed files with 9,221 additions and 8,990 deletions.
93 changes: 80 additions & 13 deletions src/fragmentarium/domain/Date.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ describe('MesopotamianDate', () => {
})
})

describe('converts from json with missing properties', () => {
it('handles missing optional properties', () => {
const json = {
year: { value: '2023' },
month: { value: '5' },
day: { value: '12' },
}

const date = MesopotamianDate.fromJson(json)

expect(date.year.value).toBe('2023')
expect(date.month.value).toBe('5')
expect(date.day.value).toBe('12')
expect(date.king).toBeUndefined()
expect(date.eponym).toBeUndefined()
expect(date.isSeleucidEra).toBeUndefined()
expect(date.isAssyrianDate).toBeUndefined()
expect(date.ur3Calendar).toBeUndefined()
})
})

describe('converts to string', () => {
it('returns the correct string representation (standard)', () => {
const date = new MesopotamianDate(
Expand All @@ -62,7 +83,7 @@ describe('MesopotamianDate', () => {
{ value: '12' },
king
)
expect(date.toString()).toBe('12.V.10 Sargon')
expect(date.toString()).toBe('12.V.10 Sargon (ca. 2325 BCE)')
})
})

Expand All @@ -75,7 +96,7 @@ describe('MesopotamianDate', () => {
undefined,
true
)
expect(date.toString()).toBe('12.V.10 SE')
expect(date.toString()).toBe('12.V.10 SE (30 August 302 BCE)')
})

it('returns the correct string representation (Ur III)', () => {
Expand All @@ -89,8 +110,9 @@ describe('MesopotamianDate', () => {
false,
Ur3Calendar.UR
)

expect(date.toString()).toBe('12.V.10 Amar-Suen, Ur calendar')
expect(date.toString()).toBe(
'12.V.10 Amar-Suen, Ur calendar (ca. 2035 BCE)'
)
})

it('returns the correct string representation (Assyrian date with eponym)', () => {
Expand All @@ -105,7 +127,9 @@ describe('MesopotamianDate', () => {
undefined
)

expect(date.toString()).toBe('1.I.1 Adad-nērārī (II) (NA eponym)')
expect(date.toString()).toBe(
'1.I.1 Adad-nērārī (II) (NA eponym) (ca. 910 BCE)'
)
})

it('returns the correct string representation (empty)', () => {
Expand All @@ -115,8 +139,7 @@ describe('MesopotamianDate', () => {
{ value: '' },
king
)

expect(date.toString()).toBe('∅.∅.∅ Sargon')
expect(date.toString()).toBe('∅.∅.∅ Sargon (ca. 2334–2279 BCE)')
})

it('returns the correct string representation (empty)', () => {
Expand All @@ -126,8 +149,7 @@ describe('MesopotamianDate', () => {
{ value: '' },
king
)

expect(date.toString()).toBe('∅.∅.∅ Sargon')
expect(date.toString()).toBe('∅.∅.∅ Sargon (ca. 2334–2279 BCE)')
})

it('returns the correct string representation (broken)', () => {
Expand All @@ -138,7 +160,7 @@ describe('MesopotamianDate', () => {
king
)

expect(date.toString()).toBe('[x].[x]².[x] Sargon')
expect(date.toString()).toBe('[x].[x]².[x] Sargon (ca. 2334–2279 BCE)')
})

it('returns the correct string representation (uncertain)', () => {
Expand All @@ -148,8 +170,7 @@ describe('MesopotamianDate', () => {
{ value: '3', isUncertain: true },
king
)

expect(date.toString()).toBe('3?.II²?.1? Sargon')
expect(date.toString()).toBe('3?.II²?.1? Sargon (ca. 2334 BCE)')
})

it('returns the correct string representation (broken and uncertain)', () => {
Expand All @@ -159,7 +180,53 @@ describe('MesopotamianDate', () => {
{ value: '3', isBroken: true, isUncertain: true },
king
)
expect(date.toString()).toBe('[x]?.[x]²?.[x]? Sargon (ca. 2334–2279 BCE)')
})

describe('toModernDate branching', () => {
it('returns empty when none of the conditions are met', () => {
const date = new MesopotamianDate(
{ value: '1' },
{ value: '1' },
{ value: '1' }
)
expect(date.toModernDate()).toBe('')
})

it('returns the correct modern date for a king without orderGlobal', () => {
const unorderedKing = { ...king, orderGlobal: -1 }
const date = new MesopotamianDate(
{ value: '10' },
{ value: '5' },
{ value: '12' },
unorderedKing
)
expect(date.toModernDate()).toBe('ca. 2325 BCE')
})
})

it('handles king with orderGlobal matching rulerToBrinkmanKings', () => {
const kingWithSpecificOrder = { ...king, orderGlobal: 1 }
const date = new MesopotamianDate(
{ value: '1' },
{ value: '1' },
{ value: '1' },
kingWithSpecificOrder
)

const result = date.toModernDate()
expect(result).toBe('ca. 2334 BCE')
})

it('handles king without a date', () => {
const kingWithoutDate = { ...king, date: '' }
const date = new MesopotamianDate(
{ value: '1' },
{ value: '1' },
{ value: '1' },
kingWithoutDate
)

expect(date.toString()).toBe('[x]?.[x]²?.[x]? Sargon')
expect(date.toModernDate()).toBe('')
})
})
59 changes: 56 additions & 3 deletions src/fragmentarium/domain/Date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Eponym } from 'common/Eponyms'
import { MesopotamianDateDto } from 'fragmentarium/domain/FragmentDtos'
import _ from 'lodash'
import { romanize } from 'romans'
import DateConverter from 'fragmentarium/domain/DateConverter'
import data from 'fragmentarium/domain/dateConverterData.json'

export interface DateField {
value: string
Expand Down Expand Up @@ -83,9 +85,11 @@ export class MesopotamianDate {
this.monthToString(),
this.yearToString(),
]
let modernDate = this.toModernDate()
modernDate = modernDate ? ` (${modernDate})` : ''
return `${dateParts.join(
'.'
)}${this.kingEponymOrEraToString()}${this.ur3CalendarToString()}`
)}${this.kingEponymOrEraToString()}${this.ur3CalendarToString()}${modernDate}`
}

private parameterToString(
Expand Down Expand Up @@ -146,8 +150,57 @@ export class MesopotamianDate {
return this.ur3Calendar ? `, ${this.ur3Calendar} calendar` : ''
}

toGregorian(): string {
// ToDo: WiP, implement
toModernDate(): string {
const year = parseInt(this.year.value)
const month = parseInt(this.month.value)
const day = parseInt(this.day.value)
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(
year: number,
month: number,
day: number
): string {
const converter = new DateConverter()
converter.setSeBabylonianDate(year, month, day)
return converter.toModernDateString()
}

private nabonassarEraToModernDate(
year: number,
month: number,
day: number
): string {
const kingName = Object.keys(data.rulerToBrinkmanKings).find(
(key) => data.rulerToBrinkmanKings[key] === this.king?.orderGlobal
)
if (kingName) {
const converter = new DateConverter()
converter.setMesopotamianDate(kingName, year, month, day)
return converter.toModernDateString()
}
return ''
}
private kingToModernDate(year?: number): string {
const firstReignYear = this.king?.date?.split('-')[0]
return firstReignYear !== undefined && year && !this.year.isBroken
? `ca. ${parseInt(firstReignYear) - year + 1} BCE`
: this.king?.date && !['', '?'].includes(this.king?.date)
? `ca. ${this.king?.date} BCE`
: ''
}
}
115 changes: 67 additions & 48 deletions src/fragmentarium/domain/DateConverter.test.ts
Original file line number Diff line number Diff line change
@@ -1,74 +1,93 @@
import DateConverter from './DateConverter'

describe('DateConverter', () => {
let babylonDate: DateConverter
let mesopotamianDate: DateConverter

beforeEach(() => {
babylonDate = new DateConverter()
mesopotamianDate = new DateConverter()
})

test('Set modern date', () => {
babylonDate.setToModernDate(-310, 3, 3)
const expected = {
year: -310,
month: 3,
year: -560,
month: 4,
day: 3,
bcYear: '311',
julianDay: 1607892,
weekDay: 1,
babylonianDay: 29,
babylonianMonth: 11,
babylonianRuler: '4 Alexander IV Aegus',
seBabylonianYear: '0',
seMacedonianYear: '1',
arsacidYear: ' ',
babylonianLunation: 5393,
babylonianMonthLength: 29,
bcYear: 561,
cjdn: 1516611,
weekDay: 7,
mesopotamianDay: 28,
mesopotamianMonth: 12,
mesopotamianMonthLength: 30,
ruler: 'Nebuchadnezzar II',
regnalYear: 43,
seBabylonianYear: -250,
lunationNabonassar: 2302,
}
expect(babylonDate.calendar).toEqual(expected)
mesopotamianDate.setToModernDate(-560, 4, 3)
expect(mesopotamianDate.calendar).toEqual(expected)
expect(mesopotamianDate.toModernDateString()).toEqual('3 April 561 BCE')
})

test('Set Babylonian date', () => {
// WiP.
// ToDo: Update to properly test.
babylonDate.setBabylonianDate(-200, 10, 1)
test('Set Mesopotamian date', () => {
const expected = {
year: -625,
month: 11,
day: 27,
bcYear: '626',
julianDay: 1493107,
weekDay: 2,
babylonianDay: 1,
babylonianMonth: 9,
babylonianRuler: '1 Interregnum',
seBabylonianYear: '-314',
seMacedonianYear: ' ',
arsacidYear: ' ',
babylonianLunation: 1507,
babylonianMonthLength: 30,
year: -580,
month: 1,
day: 3,
bcYear: 581,
cjdn: 1509215,
weekDay: 3,
mesopotamianDay: 14,
mesopotamianMonth: 10,
mesopotamianMonthLength: 29,
ruler: 'Nebuchadnezzar II',
regnalYear: 23,
lunationNabonassar: 2052,
seBabylonianYear: -270,
}
mesopotamianDate.setMesopotamianDate('Nebuchadnezzar II', 23, 10, 14)
expect(mesopotamianDate.calendar).toEqual(expected)
expect(mesopotamianDate.toModernDateString()).toEqual('3 January 581 BCE')
})

test('Set Seleucid date', () => {
mesopotamianDate.setSeBabylonianDate(100, 12, 26)
const expected = {
lunationNabonassar: 6631,
ruler: 'Antiochus III [the Great]',
regnalYear: 11,
bcYear: 211,
day: 3,
cjdn: 1644448,
month: 4,
seBabylonianYear: 100,
seMacedonianYear: 101,
seArsacidYear: 36,
mesopotamianDay: 26,
mesopotamianMonth: 12,
mesopotamianMonthLength: 29,
weekDay: 3,
year: -210,
}
expect(babylonDate.calendar).toEqual(expected)
expect(mesopotamianDate.calendar).toEqual(expected)
expect(mesopotamianDate.toModernDateString()).toEqual('3 April 211 BCE')
})

test('Offset year', () => {
babylonDate.offsetYear(100)
expect(babylonDate.calendar.year).toBe(-210)
mesopotamianDate.offsetYear(100)
expect(mesopotamianDate.calendar.year).toBe(-210)
expect(mesopotamianDate.toModernDateString()).toEqual('3 March 211 BCE')
})

test('Offset month', () => {
babylonDate.offsetMonth(5)
expect(babylonDate.calendar.month).toBe(8)
expect(babylonDate.calendar.year).toBe(-310)
mesopotamianDate.offsetMonth(5)
expect(mesopotamianDate.calendar.month).toBe(8)
expect(mesopotamianDate.calendar.year).toBe(-310)
expect(mesopotamianDate.toModernDateString()).toEqual('3 August 311 BCE')
})

test('Offset day', () => {
babylonDate.offsetDay(10)
expect(babylonDate.calendar.day).toBe(13)
})

test('Get current day', () => {
babylonDate.calendar.day = 25
expect(babylonDate.getCurrentDay()).toBe(25)
mesopotamianDate.offsetDay(10)
expect(mesopotamianDate.calendar.day).toBe(13)
expect(mesopotamianDate.toModernDateString()).toEqual('13 March 311 BCE')
})
})
Loading

0 comments on commit 4b8347f

Please sign in to comment.