Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modern date display #393

Merged
merged 41 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
956b29e
Implement Mesopotamian date, editing component & date converter (WiP)
khoidt Jul 19, 2023
4b3111e
Improve
khoidt Jul 19, 2023
c150438
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Jul 19, 2023
bec1458
Extend (WiP)
khoidt Jul 31, 2023
84c3d60
Fix and update tests
khoidt Aug 1, 2023
d5d212a
Fix tsc
khoidt Aug 1, 2023
36b15ad
Improve & update tests
khoidt Aug 1, 2023
357fdda
Fix tsc
khoidt Aug 1, 2023
0492249
Refactor
khoidt Aug 1, 2023
92dd7c9
Adjust and unify
khoidt Aug 2, 2023
5c1f265
Update & fix
khoidt Aug 5, 2023
1b9279f
Implement date display in fragmentarium search
khoidt Aug 5, 2023
8546d86
Date paleography
khoidt Aug 7, 2023
81e1ccb
Fix tests
khoidt Aug 7, 2023
5b42cba
Make `date` optional in `CroppedAnnotation`
khoidt Aug 7, 2023
3123ba0
Update style
khoidt Aug 7, 2023
e505fd6
Refactor & update
khoidt Aug 7, 2023
e41636e
Add tests & update
khoidt Aug 7, 2023
c3d21d5
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Aug 10, 2023
bb435be
Implement date delete & fix display issue
khoidt Aug 14, 2023
fc1a5d7
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Aug 16, 2023
525ed06
Implement dates in text
khoidt Aug 24, 2023
ad96479
Add tests
khoidt Aug 25, 2023
b0bfd7c
Add more tests
khoidt Aug 25, 2023
22166ea
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Aug 28, 2023
fbfedb7
Adjust date display
khoidt Aug 28, 2023
bf526e1
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Aug 29, 2023
41a0257
Implement eponyms (WiP)
khoidt Sep 4, 2023
5b6675c
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Sep 4, 2023
4df82dc
Add phases and improve selection
khoidt Sep 4, 2023
7460ee8
Extend eponym
khoidt Sep 5, 2023
088c5d3
Improve & add tests
khoidt Sep 5, 2023
111df01
Add & update tests
khoidt Sep 6, 2023
03fc524
Add test for date with eponym string
khoidt Sep 6, 2023
ba52efd
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Sep 7, 2023
ae397c3
Implement date converter
khoidt Sep 21, 2023
b325ede
Merge remote-tracking branch 'origin/master' into add-date-to-fragment
khoidt Sep 22, 2023
4768f48
Refactor
khoidt Sep 22, 2023
c3fa9fb
Refactor more
khoidt Sep 22, 2023
2f4d3e9
Refactor more
khoidt Sep 22, 2023
1a875b6
Add tests
khoidt Sep 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading