Skip to content

feat(#255): Datetime picker doesn't have seconds option #417

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

<mat-checkbox [(ngModel)]="withSeconds">withSeconds</mat-checkbox>
<form [formGroup]="group">
<mat-form-field>
<mat-label>DateTime</mat-label>
<mtx-datetimepicker-toggle [for]="datetimePicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #datetimePicker startView="month" [timeInterval]="5"></mtx-datetimepicker>
<mtx-datetimepicker #datetimePicker startView="month" [timeInterval]="5" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="datetimePicker" [max]="tomorrow" [min]="today"
autocomplete="false" formControlName="dateTime" matInput required>
<mat-error *ngIf="group.get('dateTime')?.errors?.required">required</mat-error>
Expand All @@ -14,19 +16,20 @@
<mat-label>DateTime with manual input</mat-label>
<mtx-datetimepicker-toggle [for]="datetimePickerManual" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #datetimePickerManual startView="month" [timeInterval]="5"
[timeInput]="true"></mtx-datetimepicker>
[timeInput]="true" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="datetimePickerManual" [max]="tomorrow" [min]="today"
autocomplete="false" formControlName="dateTimeManual" matInput required>
<mat-error *ngIf="group.get('dateTimeManual')?.errors?.required">required</mat-error>
<mat-error *ngIf="group.get('dateTimeManual')?.errors?.mtxDatetimepickerMin">min</mat-error>
<mat-error *ngIf="group.get('dateTimeManual')?.errors?.mtxDatetimepickerMax">max</mat-error>
</mat-form-field>


<mat-form-field>
<mat-label>DateTime Year selector</mat-label>
<mtx-datetimepicker-toggle [for]="datetimeYearPicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #datetimeYearPicker [multiYearSelector]="true" startView="month"
[timeInterval]="5"></mtx-datetimepicker>
[timeInterval]="5" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="datetimeYearPicker" [max]="tomorrow" [min]="today"
autocomplete="false" formControlName="dateTimeYear" matInput required>
<mat-error *ngIf="group.get('dateTimeYear')?.errors?.required">required</mat-error>
Expand All @@ -37,7 +40,7 @@
<mat-form-field>
<mat-label>Time</mat-label>
<mtx-datetimepicker-toggle [for]="timePicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #timePicker [timeInterval]="5" type="time"></mtx-datetimepicker>
<mtx-datetimepicker #timePicker [timeInterval]="5" type="time" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="timePicker" formControlName="time" matInput required>
<mat-error *ngIf="group.get('time')?.errors?.required">required</mat-error>
</mat-form-field>
Expand All @@ -46,7 +49,7 @@
<mat-label>Time AM/PM</mat-label>
<mtx-datetimepicker-toggle [for]="timeAMPMPicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #timeAMPMPicker [timeInterval]="5"
[twelvehour]="true" type="time"></mtx-datetimepicker>
[twelvehour]="true" type="time" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="timeAMPMPicker" formControlName="timeAMPM" matInput required>
<mat-error *ngIf="group.get('timeAMPM')?.errors?.required">required</mat-error>
</mat-form-field>
Expand All @@ -55,7 +58,7 @@
<mat-label>DateTime AM/PM with manual input</mat-label>
<mtx-datetimepicker-toggle [for]="timeAMPMPickerManual" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #timeAMPMPickerManual startView="month" [timeInterval]="5"
[timeInput]="true" [twelvehour]="true"></mtx-datetimepicker>
[timeInput]="true" [twelvehour]="true" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="timeAMPMPickerManual" [max]="tomorrow" [min]="today"
autocomplete="false" formControlName="timeAMPMManual" matInput required>
<mat-error *ngIf="group.get('timeAMPMManual')?.errors?.required">required</mat-error>
Expand All @@ -66,24 +69,23 @@
<mat-form-field>
<mat-label>Date</mat-label>
<mtx-datetimepicker-toggle [for]="datePicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #datePicker type="date"></mtx-datetimepicker>
<mtx-datetimepicker #datePicker type="date" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="datePicker" formControlName="date" matInput required>
<mat-error *ngIf="group.get('date')?.errors?.required">required</mat-error>
</mat-form-field>

<mat-form-field>
<mat-label>Month</mat-label>
<mtx-datetimepicker-toggle [for]="monthPicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #monthPicker mode="portrait" type="month">
</mtx-datetimepicker>
<mtx-datetimepicker #monthPicker mode="portrait" type="month" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="monthPicker" formControlName="month" matInput required>
<mat-error *ngIf="group.get('month')?.errors?.required">required</mat-error>
</mat-form-field>

<mat-form-field>
<mat-label>Year</mat-label>
<mtx-datetimepicker-toggle [for]="yearPicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #yearPicker type="year"></mtx-datetimepicker>
<mtx-datetimepicker #yearPicker type="year" [withSeconds]="withSeconds"></mtx-datetimepicker>
<input [mtxDatetimepicker]="yearPicker" formControlName="year" matInput required>
<mat-error *ngIf="group.get('year')?.errors?.required">required</mat-error>
</mat-form-field>
Expand All @@ -93,7 +95,7 @@
<input [mtxDatetimepicker]="minTestPicker" [max]="max" [min]="min" formControlName="mintest"
matInput required>
<mtx-datetimepicker-toggle [for]="minTestPicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #minTestPicker mode="landscape" [timeInterval]="5"></mtx-datetimepicker>
<mtx-datetimepicker #minTestPicker mode="landscape" [timeInterval]="5" [withSeconds]="withSeconds"></mtx-datetimepicker>
<mat-error *ngIf="group.get('mintest')?.errors?.required">required</mat-error>
<mat-error *ngIf="group.get('mintest')?.errors?.mtxDatetimepickerMin">min</mat-error>
<mat-error *ngIf="group.get('mintest')?.errors?.mtxDatetimepickerMax">max</mat-error>
Expand All @@ -104,7 +106,7 @@
<input [mtxDatetimepickerFilter]="filter" [mtxDatetimepicker]="filterTestPicker"
formControlName="filtertest" matInput required>
<mtx-datetimepicker-toggle [for]="filterTestPicker" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #filterTestPicker mode="landscape" [timeInterval]="5"></mtx-datetimepicker>
<mtx-datetimepicker #filterTestPicker mode="landscape" [timeInterval]="5" [withSeconds]="withSeconds"></mtx-datetimepicker>
<mat-error *ngIf="group.get('filtertest')?.errors?.required">required</mat-error>
<mat-error *ngIf="group.get('filtertest')?.errors?.mtxDatetimepickerFilter">filter</mat-error>
</mat-form-field>
Expand All @@ -113,8 +115,7 @@
<mat-label>TouchUi</mat-label>
<input [mtxDatetimepicker]="touch" [min]="min" formControlName="touch" matInput required>
<mtx-datetimepicker-toggle [for]="touch" matSuffix></mtx-datetimepicker-toggle>
<mtx-datetimepicker #touch mode="portrait" [timeInterval]="5" [touchUi]="true">
</mtx-datetimepicker>
<mtx-datetimepicker #touch mode="portrait" [timeInterval]="5" [touchUi]="true" [withSeconds]="withSeconds"></mtx-datetimepicker>
<mat-error *ngIf="group.get('touch')?.errors?.required">required</mat-error>
</mat-form-field>

Expand All @@ -124,12 +125,12 @@
<h2>Calendar Inline</h2>

<mat-card class="demo-inline-card">
<mtx-calendar (selectedChange)="selectedDate = $event" type="date" startView="month"></mtx-calendar>
<mtx-calendar (selectedChange)="selectedDate = $event" type="date" startView="month" [withSeconds]="withSeconds"></mtx-calendar>
</mat-card>
<p>Selected date: {{selectedDate}}</p>

<mat-card class="demo-inline-card">
<mtx-calendar (selectedChange)="selectedTime = $event" type="time" startView="clock">
<mtx-calendar (selectedChange)="selectedTime = $event" type="time" startView="clock" [withSeconds]="withSeconds">
</mtx-calendar>
</mat-card>
<p>Selected time: {{selectedTime}}</p>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ import { MtxDatetimepickerFilterType } from '@ng-matero/extensions/datetimepicke
styleUrls: ['datetimepicker-demo.component.scss'],
})
export class DatetimepickerDemoComponent implements OnInit, OnDestroy {
private _withSeconds = false;
public set withSeconds(val: boolean) {
this._withSeconds = val;
localStorage.setItem('withSeconds', JSON.stringify(val));
window.location.reload();
}
public get withSeconds() {
return this._withSeconds;
}
type = 'moment';

group: UntypedFormGroup;
Expand All @@ -30,23 +39,31 @@ export class DatetimepickerDemoComponent implements OnInit, OnDestroy {
private dateAdapter: DateAdapter<any>,
private translate: TranslateService
) {
const tmpWithSeconds = localStorage.getItem('withSeconds');
this._withSeconds = tmpWithSeconds ? JSON.parse(tmpWithSeconds) : false;

this.today = moment.utc();
this.tomorrow = moment.utc().date(moment.utc().date() + 1);
this.yesterday = moment.utc().date(moment.utc().date() - 1);
this.min = this.today.clone().year(2018).month(10).date(3).hour(11).minute(10);
this.max = this.min.clone().date(4).minute(45);
this.start = this.today.clone().year(1930).month(9).date(28);
this.filter = (date: moment.Moment | null, type: MtxDatetimepickerFilterType) => {
if (date === null) {
this.filter = (date: moment.Moment | null, type: MtxDatetimepickerFilterType): boolean => {
if (!date) {
return true;
}

const isEven = (value: number) => value % 2 === 0;

switch (type) {
case MtxDatetimepickerFilterType.DATE:
return date.year() % 2 === 0 && date.month() % 2 === 0 && date.date() % 2 === 0;
return isEven(date.year()) && isEven(date.month()) && isEven(date.date());
case MtxDatetimepickerFilterType.HOUR:
return date.hour() % 2 === 0;
return isEven(date.hour());
case MtxDatetimepickerFilterType.MINUTE:
return date.minute() % 2 === 0;
return isEven(date.minute());
case MtxDatetimepickerFilterType.SECOND:
return isEven(date.second());
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ import { DatetimepickerDemoComponent } from './datetimepicker-demo.component';
monthInput: 'MMMM',
yearInput: 'YYYY',
timeInput: 'HH:mm',
timeWithSecondsInput: 'HH:mm:ss',
datetimeInput: 'YYYY-MM-DD HH:mm',
datetimeWithSecondsInput: 'YYYY-MM-DD HH:mm:ss',
},
display: {
dateInput: 'YYYY-MM-DD',
monthInput: 'MMMM',
yearInput: 'YYYY',
timeInput: 'HH:mm',
timeWithSecondsInput: 'HH:mm:ss',
datetimeInput: 'YYYY-MM-DD HH:mm',
datetimeWithSecondsInput: 'YYYY-MM-DD HH:mm:ss',
monthYearLabel: 'YYYY MMMM',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,18 @@ import { MTX_DATETIME_FORMATS } from '@ng-matero/extensions/core';
monthInput: 'MMMM',
yearInput: 'YYYY',
timeInput: 'HH:mm',
timeWithSecondsInput: 'HH:mm:ss',
datetimeInput: 'YYYY-MM-DD HH:mm',
datetimeWithSecondsInput: 'YYYY-MM-DD HH:mm:ss',
},
display: {
dateInput: 'YYYY-MM-DD',
monthInput: 'MMMM',
yearInput: 'YYYY',
timeInput: 'HH:mm',
timeWithSecondsInput: 'HH:mm:ss',
datetimeInput: 'YYYY-MM-DD HH:mm',
datetimeWithSecondsInput: 'YYYY-MM-DD HH:mm:ss',
monthYearLabel: 'YYYY MMMM',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
Expand Down
29 changes: 27 additions & 2 deletions projects/extensions-date-fns-adapter/adapter/date-fns-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import {
addHours,
addMinutes,
addMonths,
addSeconds,
getHours,
getMinutes,
getSeconds,
isValid,
startOfMonth,
} from 'date-fns';
Expand Down Expand Up @@ -41,12 +43,23 @@ export class DateFnsDateTimeAdapter extends DatetimeAdapter<Date> {
return getMinutes(date);
}

getSecond(date: Date): number {
return getSeconds(date);
}

isInNextMonth(startDate: Date, endDate: Date): boolean {
const nextMonth = this.getDateInNextMonth(startDate);
return super.sameMonthAndYear(nextMonth, endDate);
}

createDatetime(year: number, month: number, day: number, hour: number, minute: number): Date {
createDatetime(
year: number,
month: number,
day: number,
hour: number,
minute: number,
second: number
): Date {
if (month < 0 || month > 11) {
throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
}
Expand All @@ -63,7 +76,11 @@ export class DateFnsDateTimeAdapter extends DatetimeAdapter<Date> {
throw Error(`Invalid minute "${minute}". Minute has to be between 0 and 59.`);
}

const result = new Date(year, month, day, hour, minute);
if (second < 0 || second > 59) {
throw Error(`Invalid second "${second}". Second has to be between 0 and 59.`);
}

const result = new Date(year, month, day, hour, minute, second);

if (!isValid(result)) {
throw Error(`Invalid date "${day}" for month with index "${month}".`);
Expand All @@ -84,6 +101,10 @@ export class DateFnsDateTimeAdapter extends DatetimeAdapter<Date> {
return range(60, i => i.toLocaleString(this.locale));
}

getSecondsNames(): string[] {
return range(60, i => i.toLocaleString(this.locale));
}

addCalendarHours(date: Date, hours: number): Date {
return addHours(date, hours);
}
Expand All @@ -92,6 +113,10 @@ export class DateFnsDateTimeAdapter extends DatetimeAdapter<Date> {
return addMinutes(date, minutes);
}

addCalendarSeconds(date: Date, seconds: number): Date {
return addSeconds(date, seconds);
}

deserialize(value: any): Date | null {
return this._delegate.deserialize(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,23 @@ export class LuxonDatetimeAdapter extends DatetimeAdapter<DateTime> {
return date.minute;
}

getSecond(date: DateTime): number {
return date.second;
}

isInNextMonth(startDate: DateTime, endDate: DateTime): boolean {
const nextMonth = this.getDateInNextMonth(startDate);
return super.sameMonthAndYear(nextMonth, endDate);
}

createDatetime(year: number, month: number, day: number, hour: number, minute: number): DateTime {
createDatetime(
year: number,
month: number,
day: number,
hour: number,
minute: number,
second: number
): DateTime {
if (month < 0 || month > 11) {
throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
}
Expand All @@ -65,12 +76,16 @@ export class LuxonDatetimeAdapter extends DatetimeAdapter<DateTime> {
throw Error(`Invalid minute "${minute}". Minute has to be between 0 and 59.`);
}

if (second < 0 || second > 59) {
throw Error(`Invalid second "${second}". Second has to be between 0 and 59.`);
}

// Luxon uses 1-indexed months so we need to add one to the month.
let result;
if (this._useUtc) {
result = DateTime.utc(year, month + 1, day, hour, minute);
result = DateTime.utc(year, month + 1, day, hour, minute, second);
} else {
result = DateTime.local(year, month + 1, day, hour, minute);
result = DateTime.local(year, month + 1, day, hour, minute, second);
}

if (!result.isValid) {
Expand All @@ -92,6 +107,10 @@ export class LuxonDatetimeAdapter extends DatetimeAdapter<DateTime> {
return range(60, i => i.toLocaleString(this.locale));
}

getSecondsNames(): string[] {
return range(60, i => i.toLocaleString(this.locale));
}

addCalendarHours(date: DateTime, hours: number): DateTime {
return date.plus({ hours });
}
Expand All @@ -100,6 +119,10 @@ export class LuxonDatetimeAdapter extends DatetimeAdapter<DateTime> {
return date.plus({ minutes });
}

addCalendarSeconds(date: DateTime, seconds: number): DateTime {
return date.plus({ seconds });
}

deserialize(value: any): DateTime | null {
return this._delegate.deserialize(value);
}
Expand Down
Loading