diff --git a/core/src/components/datetime/test/data.spec.ts b/core/src/components/datetime/test/data.spec.ts index 0fd92e3778e..e557f2c03a3 100644 --- a/core/src/components/datetime/test/data.spec.ts +++ b/core/src/components/datetime/test/data.spec.ts @@ -65,10 +65,10 @@ describe('generateTime()', () => { hour: 2, minute: 40 } - const { hours, minutes } = generateTime(today, false, min); + const { hours, minutes } = generateTime(today, 'h12', min); expect(hours.length).toEqual(11); - expect(minutes.length).toEqual(20); + expect(minutes.length).toEqual(60); }) it('should not filter according to min if not on reference day', () => { const today = { @@ -203,9 +203,59 @@ describe('generateTime()', () => { minute: 43 } - const { hours, minutes, use24Hour } = generateTime(today, 'h12', undefined, undefined, [1,2,3], [10,15,20]); + const { hours, minutes, use24Hour } = generateTime(today, 'h12', undefined, undefined, [1, 2, 3], [10, 15, 20]); + + expect(hours).toStrictEqual([1, 2, 3]); + expect(minutes).toStrictEqual([10, 15, 20]); + }) + + describe('hourCycle is 23', () => { + + it('should return hours in 24 hour format', () => { + const refValue = { + day: undefined, + month: undefined, + year: undefined, + hour: 19, + minute: 50 + } + + const minParts = { + day: undefined, + month: undefined, + year: undefined, + hour: 19, + minute: 50 + }; + + const { hours } = generateTime(refValue, 'h23', minParts); + + expect(hours).toStrictEqual([19, 20, 21, 22, 23]); + }); + + describe('current hour is above min hour range', () => { + it('should return minutes above the min minute range', () => { + const refValue = { + day: undefined, + month: undefined, + year: undefined, + hour: 20, + minute: 22 + } + + const minParts = { + day: undefined, + month: undefined, + year: undefined, + hour: 19, + minute: 30 + }; + + const { hours, minutes } = generateTime(refValue, 'h23', minParts); - expect(hours).toStrictEqual([1,2,3]); - expect(minutes).toStrictEqual([10,15,20]); + expect(hours).toStrictEqual([19, 20, 21, 22, 23]); + expect(minutes.length).toEqual(60); + }); + }); }) }) diff --git a/core/src/components/datetime/test/minmax/index.html b/core/src/components/datetime/test/minmax/index.html index a6f93975e6d..3a92d412e68 100644 --- a/core/src/components/datetime/test/minmax/index.html +++ b/core/src/components/datetime/test/minmax/index.html @@ -66,6 +66,15 @@

AM/PM Min/Max

value="10:30" > +
+

h23 Min

+ +
diff --git a/core/src/components/datetime/utils/data.ts b/core/src/components/datetime/utils/data.ts index 6fcb37a3461..4630dd17007 100644 --- a/core/src/components/datetime/utils/data.ts +++ b/core/src/components/datetime/utils/data.ts @@ -137,7 +137,8 @@ export const generateTime = ( hourValues?: number[], minuteValues?: number[] ) => { - let processedHours = hourCycle === 'h23' ? hour23 : hour12; + const use24Hour = hourCycle === 'h23'; + let processedHours = use24Hour ? hour23 : hour12; let processedMinutes = minutes; let isAMAllowed = true; let isPMAllowed = true; @@ -166,17 +167,36 @@ export const generateTime = ( if (minParts.hour !== undefined) { processedHours = processedHours.filter(hour => { const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour; - return convertedHour >= minParts.hour!; + return (use24Hour ? hour : convertedHour) >= minParts.hour!; }); isAMAllowed = minParts.hour < 13; } if (minParts.minute !== undefined) { - processedMinutes = processedMinutes.filter(minute => minute >= minParts.minute!); + /** + * The minimum minute range should not be enforced when + * the hour is greater than the min hour. + * + * For example with a minimum range of 09:30, users + * should be able to select 10:00-10:29 and beyond. + */ + let isPastMinHour = false; + if (minParts.hour !== undefined && refParts.hour !== undefined) { + if (refParts.hour > minParts.hour) { + isPastMinHour = true; + } + } + + processedMinutes = processedMinutes.filter(minute => { + if (isPastMinHour) { + return true; + } + return minute >= minParts.minute!; + }); } - /** - * If ref day is before minimum - * day do not render any hours/minute values - */ + /** + * If ref day is before minimum + * day do not render any hours/minute values + */ } else if (isBefore(refParts, minParts)) { processedHours = []; processedMinutes = []; @@ -207,10 +227,10 @@ export const generateTime = ( processedMinutes = processedMinutes.filter(minute => minute <= maxParts.minute!); } - /** - * If ref day is after minimum - * day do not render any hours/minute values - */ + /** + * If ref day is after minimum + * day do not render any hours/minute values + */ } else if (isAfter(refParts, maxParts)) { processedHours = []; processedMinutes = []; @@ -283,7 +303,7 @@ export const getCalendarYears = ( minParts?: DatetimeParts, maxParts?: DatetimeParts, yearValues?: number[] - ) => { +) => { if (yearValues !== undefined) { let processedYears = yearValues; if (maxParts?.year !== undefined) {