-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for comprehensive date conversion
This commit starts using the mapping of Japanese era dates to Gregorian calendar dates, enabling comprehensive date conversion. It includes accurate calculation of the time span of years and months for periods predating the adoption of the Gregorian calendar in Japan. Additionally, day-to-day conversion of Japanese era dates to Gregorian calendar dates was added.
- Loading branch information
Showing
16 changed files
with
1,090 additions
and
377 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
import { EraInfoDate, EraInfoTimeSpan } from '../content/dates'; | ||
import { DateArray, eraInfo } from '../utils/era-info'; | ||
|
||
export function calculateEraDateTimeSpan({ | ||
era, | ||
year, | ||
month, | ||
day, | ||
}: { | ||
era: string; | ||
year: number; | ||
month?: number; | ||
day?: number; | ||
}): EraInfoTimeSpan | undefined { | ||
let dateStart: EraInfoDate | undefined = undefined; | ||
let dateEnd: EraInfoDate | undefined = undefined; | ||
|
||
if (!day) { | ||
const res = calculateTimeSpanOfEraYearOrMonth(era, year, month); | ||
|
||
if (!res) { | ||
return undefined; | ||
} | ||
|
||
dateStart = dateToEraInfoDate(res.dateStart); | ||
dateEnd = dateToEraInfoDate(res.dateEnd); | ||
} else if (month) { | ||
dateStart = dateToEraInfoDate(toGregorianDate(era, year, month, day)); | ||
} | ||
|
||
if (!dateStart) { | ||
return undefined; | ||
} | ||
|
||
return { dateStart, dateEnd }; | ||
} | ||
|
||
function dateToEraInfoDate(date: Date): EraInfoDate { | ||
return { | ||
year: date.getFullYear(), | ||
month: date.getMonth() + 1, | ||
day: date.getDate(), | ||
}; | ||
} | ||
|
||
function dateArrayToDate(dateArray: DateArray, dayOffset: number = 0) { | ||
return new Date(dateArray[0], dateArray[1] - 1, dateArray[2] + dayOffset); | ||
} | ||
|
||
function toGregorianDate( | ||
era: string, | ||
year: number, | ||
month: number, | ||
day: number | ||
): Date { | ||
const dateArray = eraInfo[era].years[year][month]; | ||
const date = dateArrayToDate(dateArray, day - 1); | ||
return date; | ||
} | ||
|
||
function calculateTimeSpanOfEraYearOrMonth( | ||
era: string, | ||
year: number, | ||
month?: number | ||
): { dateStart: Date; dateEnd: Date } | undefined { | ||
const eraData = eraInfo[era]; | ||
|
||
const startOfEraDate = dateArrayToDate(eraData.start); | ||
const endOfEraDate = dateArrayToDate(eraData.end); | ||
|
||
if (!startOfEraDate || !endOfEraDate) { | ||
return undefined; | ||
} | ||
|
||
if (!(year in eraData.years)) { | ||
return undefined; | ||
} | ||
|
||
let startOfTimeSpan = startOfEraDate; | ||
|
||
if (month) { | ||
if (!(month in eraData.years[year])) { | ||
return undefined; | ||
} | ||
|
||
const startOfMonthArray = eraData.years[year][month]; | ||
|
||
startOfTimeSpan = dateArrayToDate(startOfMonthArray); | ||
} else if (1 in eraData.years[year]) { | ||
const startOfYearArray = eraData.years[year][1]; | ||
|
||
startOfTimeSpan = dateArrayToDate(startOfYearArray); | ||
} | ||
|
||
const laterStartDate = | ||
startOfEraDate > startOfTimeSpan ? startOfEraDate : startOfTimeSpan; | ||
|
||
let endOfTimeSpan = endOfEraDate; | ||
|
||
if (month) { | ||
const nextMonthIsLeapMonth = month > 0 && (-month) in eraData.years[year]; | ||
const isLastMonthInYear = !nextMonthIsLeapMonth && Math.abs(month) === 12; | ||
|
||
let nextYear = year; | ||
let nextMonth = month; | ||
|
||
if (nextMonthIsLeapMonth) { | ||
nextMonth = -nextMonth; | ||
} else if (isLastMonthInYear) { | ||
nextYear++; | ||
nextMonth = 1; | ||
} else { | ||
nextMonth = Math.abs(nextMonth) + 1; | ||
} | ||
|
||
if (nextYear in eraData.years && nextMonth in eraData.years[nextYear]) { | ||
const startOfNextMonthArray = eraData.years[nextYear][nextMonth]; | ||
|
||
endOfTimeSpan = dateArrayToDate(startOfNextMonthArray, -1); | ||
} | ||
} else { | ||
const notLastYearOfEra = year + 1 in eraData.years; | ||
if (notLastYearOfEra) { | ||
const startOfNextYearArray = eraData.years[year + 1][1]; | ||
|
||
endOfTimeSpan = dateArrayToDate(startOfNextYearArray, -1); | ||
} | ||
} | ||
|
||
const earlierEndDate = | ||
endOfEraDate < endOfTimeSpan ? endOfEraDate : endOfTimeSpan; | ||
|
||
return { | ||
dateStart: laterStartDate, | ||
dateEnd: earlierEndDate, | ||
}; | ||
} |
Oops, something went wrong.