Skip to content

Commit

Permalink
fix: use NepaliCalendar instance to validate dates
Browse files Browse the repository at this point in the history
  • Loading branch information
kabaros committed Oct 8, 2024
1 parent 179cfeb commit 537b7e2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 63 deletions.
32 changes: 25 additions & 7 deletions src/custom-calendars/nepaliCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,18 @@ class NepaliCalendar extends Temporal.Calendar {
*
* A custom implementation of these methods is used to convert the calendar-space arguments to the ISO calendar.
*/
dateFromFields(fields: CalendarYMD): Temporal.PlainDate {
const { year, day, month } = _nepaliToIso({
year: fields.year,
month: fields.month,
day: fields.day,
})
dateFromFields(
fields: CalendarYMD,
options: Temporal.AssignmentOptions
): Temporal.PlainDate {
const { year, day, month } = _nepaliToIso(
{
year: fields.year,
month: fields.month,
day: fields.day,
},
options
)
return new Temporal.PlainDate(year, month, day, this)
}
yearMonthFromFields(fields: CalendarYMD): Temporal.PlainYearMonth {
Expand All @@ -96,7 +102,10 @@ const lastSupportedNepaliYear = Number(
supportedNepaliYears[supportedNepaliYears.length - 1]
)

const _nepaliToIso = (fields: { day: number; year: number; month: number }) => {
const _nepaliToIso = (
fields: { day: number; year: number; month: number },
{ overflow }: Temporal.AssignmentOptions = {}
) => {
let { year: nepaliYear } = fields

if (
Expand All @@ -109,6 +118,15 @@ const _nepaliToIso = (fields: { day: number; year: number; month: number }) => {
}
const { month: nepaliMonth, day: nepaliDay = 1 } = fields

if (
overflow === 'reject' &&
(nepaliMonth < 1 ||
nepaliMonth > 12 ||
nepaliDay > NEPALI_CALENDAR_DATA[nepaliYear][nepaliMonth])
) {
throw new Error('Invalid date in Nepali calendar')
}

let gregorianDayOfYear = 0

let monthCounter = nepaliMonth
Expand Down
63 changes: 7 additions & 56 deletions src/utils/validate-date-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,7 @@ import { Temporal } from '@js-temporal/polyfill'
import { dhis2CalendarsMap } from '../constants/dhis2CalendarsMap'
import type { SupportedCalendar } from '../types'
import { extractDatePartsFromDateString } from './extract-date-parts-from-date-string'
import { getCustomCalendarIfExists } from './helpers'

type ValidateNepaliDateFn = (
year: number,
month: number,
day: number
) => ValidationResult

const validateNepaliDate: ValidateNepaliDateFn = (year, month, day) => {
const nepaliYearData = NEPALI_CALENDAR_DATA[year]
if (!nepaliYearData) {
return {
error: true,
validationCode: DateValidationResult.INVALID_DATE_IN_CALENDAR,
validationText: i18n.t(`Year {{year}} is out of range.`, { year }),
}
}

if (month < 1 || month > 12) {
return {
error: true,
validationCode: DateValidationResult.INVALID_DATE_IN_CALENDAR,
validationText: i18n.t(
`Month {{month}} is out of range | 1 <= {{month}} <= 12.`,
{ month }
),
}
}

const daysInMonth = nepaliYearData[month]

if (day < 1 || day > daysInMonth) {
return {
error: true,
validationCode: DateValidationResult.INVALID_DATE_IN_CALENDAR,
validationText: i18n.t(
`Day {{day}} is out of range | 1 <= {{day}} <= {{daysInMonth}}.`,
{ day, daysInMonth }
),
}
}

return {
error: false,
warning: false,
}
}
import { getCustomCalendarIfExists, isCustomCalendar } from './helpers'

type ValidationOptions = {
calendar?: SupportedCalendar
Expand Down Expand Up @@ -136,20 +90,17 @@ export const validateDateString: ValidateDateStringFn = (
validationText: e?.message,
}
}
if (resolvedCalendar.toString() === 'nepali') {
// ToDo: double check why nepali can't just be handle with Temporal.PlainDate.from
return validateNepaliDate(
dateParts.year,
dateParts.month,
dateParts.day
)
}

let date: Temporal.PlainDate

// Will throw if the year, month or day is out of range
try {
date = Temporal.PlainDate.from(
date = isCustomCalendar(resolvedCalendar)
? Temporal.Calendar.from(resolvedCalendar).dateFromFields(
dateParts,
{ overflow: 'reject' }
) // need to be handled separately for custom calendars
: Temporal.PlainDate.from(
{ ...dateParts, calendar: resolvedCalendar },
{ overflow: 'reject' }
)
Expand Down

0 comments on commit 537b7e2

Please sign in to comment.