diff --git a/components/i18n/date-helper.service.spec.ts b/components/i18n/date-helper.service.spec.ts index 925a9738f77..e3ce0149ed8 100644 --- a/components/i18n/date-helper.service.spec.ts +++ b/components/i18n/date-helper.service.spec.ts @@ -35,6 +35,11 @@ describe('DateHelperService', () => { it('should get first day of week with 0 by en_US', () => { expect(dateHelper.getFirstDayOfWeek()).toBe(0); }); + + it('should do parseTime correctly', () => { + expect(dateHelper.parseTime('14:00')?.toTimeString().substr(0, 8)).toBe('14:00:00'); + expect(dateHelper.parseTime('4:00')?.toTimeString().substr(0, 8)).toBe('04:00:00'); + }); }); describe('Formatting with Data-fns', () => { @@ -56,6 +61,11 @@ describe('DateHelperService', () => { expect(dateHelper.format(date, 'yyyy-MM-dd')).toBe('2018-12-31'); expect(dateHelper.format(date, 'II')).toBe('01'); // ISO week }); + + it('should do parseTime correctly', () => { + expect(dateHelper.parseTime('14:00', 'HH:mm')?.toTimeString().substr(0, 8)).toBe('14:00:00'); + expect(dateHelper.parseTime('4:00', 'H:mm')?.toTimeString().substr(0, 8)).toBe('04:00:00'); + }); }); describe('Custom firstDayOfWeek', () => { diff --git a/components/i18n/date-helper.service.ts b/components/i18n/date-helper.service.ts index dce142bd042..6ddefc54342 100644 --- a/components/i18n/date-helper.service.ts +++ b/components/i18n/date-helper.service.ts @@ -12,7 +12,6 @@ import fnsFormat from 'date-fns/format'; import fnsGetISOWeek from 'date-fns/getISOWeek'; import fnsParse from 'date-fns/parse'; -import parseISO from 'date-fns/parseISO'; import { WeekDayIndex } from 'ng-zorro-antd/core/time'; import { convertTokens } from './convert-tokens'; import { mergeDateConfig, NZ_DATE_CONFIG, NZ_DATE_FNS_COMPATIBLE, NzDateConfig } from './date-config'; @@ -47,13 +46,7 @@ export abstract class DateHelperService { abstract getFirstDayOfWeek(): WeekDayIndex; abstract format(date: Date, formatStr: string): string; abstract parseDate(text: string, formatStr?: string): Date; - - parseTime(text: string): Date | undefined { - if (!text) { - return; - } - return parseISO(`1970-01-01 ${text}`); - } + abstract parseTime(text: string, formatStr?: string): Date | undefined; } /** @@ -94,6 +87,10 @@ export class DateHelperByDateFns extends DateHelperService { weekStartsOn: this.getFirstDayOfWeek() }); } + + parseTime(text: string, formatStr: string): Date | undefined { + return this.parseDate(text, formatStr); + } } /** @@ -122,4 +119,11 @@ export class DateHelperByDatePipe extends DateHelperService { parseDate(text: string): Date { return new Date(text); } + + parseTime(text: string): Date | undefined { + if (!text) { + return; + } + return new Date(Date.parse(`1970-01-01 ${text}`)); + } } diff --git a/components/time-picker/time-picker-panel.component.ts b/components/time-picker/time-picker-panel.component.ts index b794f7844b1..f7a3c214647 100644 --- a/components/time-picker/time-picker-panel.component.ts +++ b/components/time-picker/time-picker-panel.component.ts @@ -404,7 +404,8 @@ export class NzTimePickerPanelComponent implements ControlValueAccessor, OnInit, scrollToSelected(instance: HTMLElement, index: number, duration: number = 0, unit: NzTimePickerUnit): void { const transIndex = this.translateIndex(index, unit); const currentOption = (instance.children[transIndex] || instance.children[0]) as HTMLElement; - this.scrollTo(instance, currentOption.offsetTop, duration); + const parentPaddingTop = 4; + this.scrollTo(instance, currentOption.offsetTop - parentPaddingTop, duration); } translateIndex(index: number, unit: NzTimePickerUnit): number { diff --git a/components/time-picker/time-picker.component.spec.ts b/components/time-picker/time-picker.component.spec.ts index 3a495210127..0b08ef1e15e 100644 --- a/components/time-picker/time-picker.component.spec.ts +++ b/components/time-picker/time-picker.component.spec.ts @@ -122,7 +122,28 @@ describe('time-picker', () => { const result = (nzOnChange.calls.allArgs()[0] as Date[])[0]; expect(result.getHours()).toBe(0); })); + it('should support ISO string', fakeAsync(() => { + testComponent.date = '2020-03-27T13:49:54.917Z'; + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + testComponent.open = true; + fixture.detectChanges(); + tick(500); + fixture.detectChanges(); + const date = new Date(testComponent.date); + expect(queryFromOverlay('.ant-picker-time-panel-column:nth-child(1) .ant-picker-time-panel-cell-selected > div')!.textContent).toBe( + date.getHours().toString() + ); + expect(queryFromOverlay('.ant-picker-time-panel-column:nth-child(2) .ant-picker-time-panel-cell-selected > div')!.textContent).toBe( + date.getMinutes().toString() + ); + })); }); + + function queryFromOverlay(selector: string): HTMLElement { + return overlayContainer.getContainerElement().querySelector(selector) as HTMLElement; + } }); @Component({ @@ -142,7 +163,7 @@ export class NzTestTimePickerComponent { open = false; openChange = jasmine.createSpy('open change'); autoFocus = false; - date = new Date(); + date: Date | string = new Date(); disabled = false; use12Hours = false; onChange(): void {} diff --git a/components/time-picker/time-picker.component.ts b/components/time-picker/time-picker.component.ts index c1f1757782a..c421ea49cd3 100644 --- a/components/time-picker/time-picker.component.ts +++ b/components/time-picker/time-picker.component.ts @@ -28,6 +28,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { slideMotion } from 'ng-zorro-antd/core/animation'; import { NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; +import { warn } from 'ng-zorro-antd/core/logger'; import { InputBoolean, isNotNil } from 'ng-zorro-antd/core/util'; const NZ_CONFIG_COMPONENT_NAME = 'timePicker'; @@ -250,8 +251,13 @@ export class NzTimePickerComponent implements ControlValueAccessor, OnInit, Afte this.updateAutoFocus(); } - writeValue(time: Date | null): void { - this.value = time; + writeValue(time: Date): void { + if (time instanceof Date) { + this.value = time; + } else { + warn('Non-Date type is not recommended for time-picker, use "Date" type'); + this.value = time ? new Date(time) : null; + } this.cdr.markForCheck(); } diff --git a/components/time-picker/time-value-accessor.directive.ts b/components/time-picker/time-value-accessor.directive.ts index cc174e5eb96..dd98f6c86b1 100644 --- a/components/time-picker/time-value-accessor.directive.ts +++ b/components/time-picker/time-value-accessor.directive.ts @@ -33,7 +33,7 @@ export class NzTimeValueAccessorDirective implements ControlValueAccessor { changed(): void { if (this._onChange) { - const value = this.dateHelper.parseTime(this.elementRef.nativeElement.value); + const value = this.dateHelper.parseTime(this.elementRef.nativeElement.value, this.nzTime); this._onChange(value!); } }