Skip to content

Commit 5b2d65b

Browse files
committed
feat(date-time-editor): fractional seconds support
1 parent 34ba51d commit 5b2d65b

File tree

6 files changed

+137
-58
lines changed

6 files changed

+137
-58
lines changed

Diff for: projects/igniteui-angular/src/lib/date-common/util/date-time.util.spec.ts

+34-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const reduceToDictionary = (parts: DatePartInfo[]) => parts.reduce((obj, x) => {
99
describe(`DateTimeUtil Unit tests`, () => {
1010
describe('Date Time Parsing', () => {
1111
it('should correctly parse all date time parts (base)', () => {
12-
const result = DateTimeUtil.parseDateTimeFormat('dd/MM/yyyy HH:mm:ss a');
12+
const result = DateTimeUtil.parseDateTimeFormat('dd/MM/yyyy HH:mm:ss:SS a');
1313
const expected = [
1414
{ start: 0, end: 2, type: DatePart.Date, format: 'dd' },
1515
{ start: 2, end: 3, type: DatePart.Literal, format: '/' },
@@ -22,8 +22,10 @@ describe(`DateTimeUtil Unit tests`, () => {
2222
{ start: 14, end: 16, type: DatePart.Minutes, format: 'mm' },
2323
{ start: 16, end: 17, type: DatePart.Literal, format: ':' },
2424
{ start: 17, end: 19, type: DatePart.Seconds, format: 'ss' },
25-
{ start: 19, end: 20, type: DatePart.Literal, format: ' ' },
26-
{ start: 20, end: 22, type: DatePart.AmPm, format: 'aa' }
25+
{ start: 19, end: 20, type: DatePart.Literal, format: ':' },
26+
{ start: 20, end: 23, type: DatePart.FractionalSeconds, format: 'SSS' },
27+
{ start: 23, end: 24, type: DatePart.Literal, format: ' ' },
28+
{ start: 24, end: 26, type: DatePart.AmPm, format: 'aa' }
2729
];
2830
expect(JSON.stringify(result)).toEqual(JSON.stringify(expected));
2931
});
@@ -235,6 +237,7 @@ describe(`DateTimeUtil Unit tests`, () => {
235237
expect(DateTimeUtil.isDateOrTimeChar('h')).toBeTrue();
236238
expect(DateTimeUtil.isDateOrTimeChar('m')).toBeTrue();
237239
expect(DateTimeUtil.isDateOrTimeChar('s')).toBeTrue();
240+
expect(DateTimeUtil.isDateOrTimeChar('S')).toBeTrue();
238241
expect(DateTimeUtil.isDateOrTimeChar(':')).toBeFalse();
239242
expect(DateTimeUtil.isDateOrTimeChar('/')).toBeFalse();
240243
expect(DateTimeUtil.isDateOrTimeChar('.')).toBeFalse();
@@ -414,6 +417,34 @@ describe(`DateTimeUtil Unit tests`, () => {
414417
expect(date.getTime()).toEqual(new Date(2015, 4, 20, 12, 59, 57).getTime());
415418
});
416419

420+
it('should spin fractional seconds portion correctly', () => {
421+
// base
422+
let date = new Date(2024, 3, 10, 6, 10, 5, 555);
423+
DateTimeUtil.spinFractionalSeconds(1, date, false);
424+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 556).getTime());
425+
DateTimeUtil.spinFractionalSeconds(-1, date, false);
426+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 555).getTime());
427+
428+
// delta !== 1
429+
DateTimeUtil.spinFractionalSeconds(5, date, false);
430+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 560).getTime());
431+
DateTimeUtil.spinFractionalSeconds(-6, date, false);
432+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 554).getTime());
433+
434+
// without looping over
435+
date = new Date(2024, 3, 10, 6, 10, 5, 999);
436+
DateTimeUtil.spinFractionalSeconds(1, date, false);
437+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 999).getTime());
438+
DateTimeUtil.spinFractionalSeconds(-1000, date, false);
439+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 0).getTime());
440+
441+
// with looping over (seconds are not affected)
442+
DateTimeUtil.spinFractionalSeconds(1001, date, true);
443+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 1).getTime());
444+
DateTimeUtil.spinFractionalSeconds(-5, date, true);
445+
expect(date.getTime()).toEqual(new Date(2024, 3, 10, 6, 10, 5, 996).getTime());
446+
});
447+
417448
it('should spin AM/PM and a/p portion correctly', () => {
418449
const currentDate = new Date(2015, 4, 31, 4, 59, 59);
419450
const newDate = new Date(2015, 4, 31, 4, 59, 59);

Diff for: projects/igniteui-angular/src/lib/date-common/util/date-time.util.ts

+26-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ export abstract class DateTimeUtil {
5656
return null;
5757
}
5858

59-
if (parts[DatePart.Hours] > 23 || parts[DatePart.Minutes] > 59 || parts[DatePart.Seconds] > 59) {
59+
if (parts[DatePart.Hours] > 23 || parts[DatePart.Minutes] > 59
60+
|| parts[DatePart.Seconds] > 59 || parts[DatePart.FractionalSeconds] > 999) {
6061
return null;
6162
}
6263

@@ -78,7 +79,8 @@ export abstract class DateTimeUtil {
7879
parts[DatePart.Date] || 1,
7980
parts[DatePart.Hours] || 0,
8081
parts[DatePart.Minutes] || 0,
81-
parts[DatePart.Seconds] || 0
82+
parts[DatePart.Seconds] || 0,
83+
parts[DatePart.FractionalSeconds] || 0
8284
);
8385
}
8486

@@ -176,6 +178,9 @@ export abstract class DateTimeUtil {
176178
case DatePart.Seconds:
177179
maskedValue = value.getSeconds();
178180
break;
181+
case DatePart.FractionalSeconds:
182+
maskedValue = value.getMilliseconds();
183+
break;
179184
case DatePart.AmPm:
180185
if (value.getHours() >= 12) {
181186
maskedValue = partLength === 1 ? 'p' : 'PM';
@@ -335,6 +340,20 @@ export abstract class DateTimeUtil {
335340
newDate.setSeconds(seconds);
336341
}
337342

343+
/** Spins the fractional seconds (milliseconds) portion in a date-time editor. */
344+
public static spinFractionalSeconds(delta: number, newDate: Date, spinLoop: boolean) {
345+
const maxMs = 999;
346+
const minMs = 0;
347+
let ms = newDate.getMilliseconds() + delta;
348+
if (ms > maxMs) {
349+
ms = spinLoop ? ms % maxMs - 1 : maxMs;
350+
} else if (ms < minMs) {
351+
ms = spinLoop ? maxMs + (ms % maxMs) + 1 : minMs;
352+
}
353+
354+
newDate.setMilliseconds(ms);
355+
}
356+
338357
/** Spins the AM/PM portion in a date-time editor. */
339358
public static spinAmPm(newDate: Date, currentDate: Date, amPmFromMask: string): Date {
340359
switch (amPmFromMask) {
@@ -543,6 +562,9 @@ export abstract class DateTimeUtil {
543562
part.format = part.format.repeat(2);
544563
}
545564
break;
565+
case DatePart.FractionalSeconds:
566+
part.format = part.format[0].repeat(3);
567+
break;
546568
}
547569
}
548570

@@ -566,8 +588,9 @@ export abstract class DateTimeUtil {
566588
case 'm':
567589
return DatePart.Minutes;
568590
case 's':
569-
case 'S':
570591
return DatePart.Seconds;
592+
case 'S':
593+
return DatePart.FractionalSeconds;
571594
case 'a':
572595
case 't':
573596
case 'T':

Diff for: projects/igniteui-angular/src/lib/directives/date-time-editor/date-time-editor.common.ts

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export enum DatePart {
1414
Hours = 'hours',
1515
Minutes = 'minutes',
1616
Seconds = 'seconds',
17+
FractionalSeconds = 'fractionalSeconds',
1718
AmPm = 'ampm',
1819
Literal = 'literal'
1920
}
@@ -34,4 +35,5 @@ export interface DatePartDeltas {
3435
hours?: number;
3536
minutes?: number;
3637
seconds?: number;
38+
fractionalSeconds?: number;
3739
}

0 commit comments

Comments
 (0)