Skip to content

Commit 326f481

Browse files
authored
fix: remove �min/max limits for all segments in parseDuration (#7064)
* fix: remove hours limit for parseDuration - Removes 23-hour limit on duration parsing - Allows parsing of durations like "PT36H" to work correctly - Aligns behavior with Temporal.Duration spec which has no upper limit on hours * fix: remove min, max limit of all segments * test: unify duration parsing test for all segments exceeding calendar constraints
1 parent b75aaa5 commit 326f481

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

packages/@internationalized/date/src/string.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -234,16 +234,14 @@ export function parseDuration(value: string): Required<DateTimeDuration> {
234234

235235
const parseDurationGroup = (
236236
group: string | undefined,
237-
isNegative: boolean,
238-
min: number,
239-
max: number
237+
isNegative: boolean
240238
): number => {
241239
if (!group) {
242240
return 0;
243241
}
244242
try {
245243
const sign = isNegative ? -1 : 1;
246-
return sign * parseNumber(group.replace(',', '.'), min, max);
244+
return sign * Number(group.replace(',', '.'));
247245
} catch {
248246
throw new Error(`Invalid ISO 8601 Duration string: ${value}`);
249247
}
@@ -267,13 +265,13 @@ export function parseDuration(value: string): Required<DateTimeDuration> {
267265
}
268266

269267
const duration: Mutable<DateTimeDuration> = {
270-
years: parseDurationGroup(match.groups?.years, isNegative, 0, 9999),
271-
months: parseDurationGroup(match.groups?.months, isNegative, 0, 12),
272-
weeks: parseDurationGroup(match.groups?.weeks, isNegative, 0, Infinity),
273-
days: parseDurationGroup(match.groups?.days, isNegative, 0, 31),
274-
hours: parseDurationGroup(match.groups?.hours, isNegative, 0, 23),
275-
minutes: parseDurationGroup(match.groups?.minutes, isNegative, 0, 59),
276-
seconds: parseDurationGroup(match.groups?.seconds, isNegative, 0, 59)
268+
years: parseDurationGroup(match.groups?.years, isNegative),
269+
months: parseDurationGroup(match.groups?.months, isNegative),
270+
weeks: parseDurationGroup(match.groups?.weeks, isNegative),
271+
days: parseDurationGroup(match.groups?.days, isNegative),
272+
hours: parseDurationGroup(match.groups?.hours, isNegative),
273+
minutes: parseDurationGroup(match.groups?.minutes, isNegative),
274+
seconds: parseDurationGroup(match.groups?.seconds, isNegative)
277275
};
278276

279277
if (duration.hours !== undefined && ((duration.hours % 1) !== 0) && (duration.minutes || duration.seconds)) {

packages/@internationalized/date/tests/string.test.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,19 @@ describe('string conversion', function () {
596596
});
597597
});
598598

599+
it('parses an ISO 8601 duration string with values exceeding normal calendar constraints', function () {
600+
const duration = parseDuration('P99Y99M99W99DT99H99M99S');
601+
expect(duration).toStrictEqual({
602+
years: 99,
603+
months: 99,
604+
weeks: 99,
605+
days: 99,
606+
hours: 99,
607+
minutes: 99,
608+
seconds: 99
609+
});
610+
});
611+
599612
it('throws an error when passed an improperly formatted ISO 8601 duration string', function () {
600613
expect(() => {
601614
parseDuration('+-P18Y7MT20H15S');
@@ -612,9 +625,6 @@ describe('string conversion', function () {
612625
expect(() => {
613626
parseDuration('P18Y7MT');
614627
}).toThrow('Invalid ISO 8601 Duration string: P18Y7MT');
615-
expect(() => {
616-
parseDuration('P18Y7MT30H15S');
617-
}).toThrow('Invalid ISO 8601 Duration string: P18Y7MT30H15S');
618628
expect(() => {
619629
parseDuration('7Y6D85');
620630
}).toThrow('Invalid ISO 8601 Duration string: 7Y6D85');

0 commit comments

Comments
 (0)