@angular/material/core#DateAdapter TypeScript Examples

The following examples show how to use @angular/material/core#DateAdapter. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
describe('NgxDateFnsDateAdapter with MAT_DATE_LOCALE override', () => {
  let adapter: NgxDateFnsDateAdapter;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NgxMatDateFnsDateModule],
        providers: [
          { provide: MAT_DATE_LOCALE, useValue: 'da' },
          { provide: NGX_MAT_DATEFNS_LOCALES, useValue: [da] },
        ],
      }).compileComponents();
    })
  );

  beforeEach(inject([DateAdapter], (d: NgxDateFnsDateAdapter) => {
    adapter = d;
  }));

  it('should take the default locale id from the MAT_DATE_LOCALE injection token', () => {
    const expectedValue = [
      'søndag',
      'mandag',
      'tirsdag',
      'onsdag',
      'torsdag',
      'fredag',
      'lørdag',
    ];

    expect(adapter.getDayOfWeekNames('long')).toEqual(expectedValue);
  });
});
Example #2
Source File: moment-js-datepicker.component.ts    From matx-angular with MIT License 6 votes vote down vote up
@Component({
  selector: 'app-moment-js-datepicker',
  templateUrl: './moment-js-datepicker.component.html',
  styleUrls: ['./moment-js-datepicker.component.scss'],
  providers: [
    // `MomentDateAdapter` and `MAT_MOMENT_DATE_FORMATS` can be automatically provided by importing
    // `MatMomentDateModule` in your applications root module. We provide it at the component level
    // here, due to limitations of our example generation script.
    {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
    {provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS},
  ],
})
export class MomentJsDatepickerComponent implements OnInit {

    // Datepicker takes `Moment` objects instead of `Date` objects.
    date = new FormControl(moment([2017, 0, 1]));

  constructor() { }

  ngOnInit() {
  }

}
Example #3
Source File: different-locale-datepicker.component.ts    From matx-angular with MIT License 6 votes vote down vote up
@Component({
  selector: 'app-different-locale-datepicker',
  templateUrl: './different-locale-datepicker.component.html',
  styleUrls: ['./different-locale-datepicker.component.scss'],
  providers: [
    // The locale would typically be provided on the root module of your application. We do it at
    // the component level here, due to limitations of our example generation script.
    {provide: MAT_DATE_LOCALE, useValue: 'ja-JP'},

    // `MomentDateAdapter` and `MAT_MOMENT_DATE_FORMATS` can be automatically provided by importing
    // `MatMomentDateModule` in your applications root module. We provide it at the component level
    // here, due to limitations of our example generation script.
    {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
    {provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS},
  ],
})
export class DifferentLocaleDatepickerComponent {

  constructor(private adapter: DateAdapter<any>) {}

  french() {
    this.adapter.setLocale('fr');
  }
}
Example #4
Source File: custom-datepicker.component.ts    From matx-angular with MIT License 6 votes vote down vote up
@Component({
  selector: 'app-custom-datepicker',
  templateUrl: './custom-datepicker.component.html',
  styleUrls: ['./custom-datepicker.component.scss'],
  providers: [
    // `MomentDateAdapter` can be automatically provided by importing `MomentDateModule` in your
    // application's root module. We provide it at the component level here, due to limitations of
    // our example generation script.
    {provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},

    {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
  ],
})
export class CustomDatepickerComponent implements OnInit {

  date = new FormControl(moment());
  
  constructor() { }

  ngOnInit() {
  }

}
Example #5
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
describe('NgxDateFnsDateAdapter with NGX_MAT_DATEFNS_LOCALES set', () => {
  let adapter: NgxDateFnsDateAdapter;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NgxMatDateFnsDateModule],
        providers: [{ provide: NGX_MAT_DATEFNS_LOCALES, useValue: [da] }],
      }).compileComponents();
    })
  );

  beforeEach(inject([DateAdapter], (d: NgxDateFnsDateAdapter) => {
    adapter = d;
  }));

  it('should throw when attempting to set locale without providing it in the NGX_MAT_DATEFNS_LOCALES token', () => {
    expect(() => adapter.setLocale('ru')).toThrowError(
      /locale \'ru\' does not exist in locales array. Add it to the NGX_MAT_DATEFNS_LOCALES token./
    );
  });
});
Example #6
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
describe('NgxDateFnsDateAdapter with MAT_DATE_LOCALE override', () => {
  let adapter: NgxDateFnsDateAdapter;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NgxMatDateFnsDateModule],
        providers: [{ provide: MAT_DATE_LOCALE, useValue: '' }],
      }).compileComponents();
    })
  );

  beforeEach(inject([DateAdapter], (d: NgxDateFnsDateAdapter) => {
    adapter = d;
  }));

  it('should load en-US locale when MAT_DATE_LOCALE is null|empty string|undefined etc ', () => {
    expect(adapter.getMonthNames('long')).toEqual([
      'January',
      'February',
      'March',
      'April',
      'May',
      'June',
      'July',
      'August',
      'September',
      'October',
      'November',
      'December',
    ]);
  });
});
Example #7
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
describe('NgxDateFnsDateAdapter with LOCALE_ID override', () => {
  let adapter: NgxDateFnsDateAdapter;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NgxMatDateFnsDateModule],
        providers: [
          { provide: LOCALE_ID, useValue: 'da' },
          { provide: NGX_MAT_DATEFNS_LOCALES, useValue: [da] },
        ],
      }).compileComponents();
    })
  );

  beforeEach(inject([DateAdapter], (d: NgxDateFnsDateAdapter) => {
    adapter = d;
  }));

  it('should cascade locale id from the LOCALE_ID injection token to MAT_DATE_LOCALE', () => {
    const expectedValue = [
      'søndag',
      'mandag',
      'tirsdag',
      'onsdag',
      'torsdag',
      'fredag',
      'lørdag',
    ];

    expect(adapter.getDayOfWeekNames('long')).toEqual(expectedValue);
  });
});
Example #8
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
describe('NgxDateFnsDateAdapter with MAT_DATE_LOCALE override', () => {
  let adapter: NgxDateFnsDateAdapter;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NgxMatDateFnsDateModule],
        providers: [{ provide: MAT_DATE_LOCALE, useValue: 'invalid' }],
      }).compileComponents();
    })
  );

  beforeEach(inject([DateAdapter], (d: NgxDateFnsDateAdapter) => {
    adapter = d;
  }));

  it('should set en-US locale when overriding the MAT_DATE_LOCALE injection token with invalid locale value', () => {
    expect(adapter.format(new Date(2017, JAN, 1), 'MMMM d, yyyy')).toEqual(
      'January 1, 2017'
    );
  });
});
Example #9
Source File: ngx-mat-datefns-date-adapter.module.ts    From ngx-mat-datefns-date-adapter with MIT License 6 votes vote down vote up
@NgModule({
  providers: [
    {
      provide: DateAdapter,
      useClass: NgxDateFnsDateAdapter,
      deps: [MAT_DATE_LOCALE, NGX_MAT_DATEFNS_LOCALES, NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS],
    },
  ],
})
export class NgxDateFnsDateModule {}
Example #10
Source File: dxc-date-input.module.ts    From halstack-angular with Apache License 2.0 6 votes vote down vote up
@NgModule({
  declarations: [DxcDateInputComponent],
  imports: [
    CommonModule,
    DxcTextInputModule,
    FormsModule,
    DxcBoxModule,
    MdePopoverModule,
    MatDayjsDateModule,
    MatDatepickerModule,
  ],
  exports: [DxcDateInputComponent],
  providers: [
    { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
    {
      provide: DateAdapter,
      useClass: DayjsDateAdapter,
      deps: [MAT_DATE_LOCALE, Platform],
    },
  ],
})
export class DxcDateInputModule {}
Example #11
Source File: team-reports-search-filter.component.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
@Component({
  selector: 'app-team-reports-search-filter',
  templateUrl: './team-reports-search-filter.component.html',
  styleUrls: ['./team-reports-search-filter.component.scss'],
  providers: [
    { provide: DateAdapter, useClass: AppDateAdapter },
    { provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS },
  ],
})
export class TeamReportsSearchFilterComponent implements OnInit {
  @Input() filters: Partial<{
    state: string;
    date: string;
    customDateStart: Date;
    customDateEnd: Date;
    sortParam: string;
    sortDir: string;
  }>;

  fg: FormGroup;

  constructor(private fb: FormBuilder, private popoverController: PopoverController) {}

  ngOnInit() {
    this.fg = this.fb.group({
      state: [this.filters && this.filters.state],
      date: [this.filters && this.filters.date],
      customDateStart: [this.filters && this.filters.customDateStart],
      customDateEnd: [this.filters && this.filters.customDateEnd],
    });

    this.fg.validator = this.customDatevalidator;
  }

  customDatevalidator(formGroup: FormGroup) {
    if (
      formGroup.value.date &&
      formGroup.value.date === 'CUSTOMDATE' &&
      (formGroup.controls.customDateStart.value === null || formGroup.controls.customDateEnd.value === null)
    ) {
      return {
        error: 'custom date input is required when custom dates are selected',
      };
    }
  }

  save() {
    if (this.fg.value.date !== 'CUSTOMDATE') {
      this.fg.controls.customDateStart.reset();
      this.fg.controls.customDateEnd.reset();
    }

    this.popoverController.dismiss({
      filters: this.fg.value,
    });
  }

  cancel() {
    this.popoverController.dismiss();
  }

  clearAll() {
    this.fg.reset();
  }
}
Example #12
Source File: my-reports-search-filter.component.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
@Component({
  selector: 'app-my-reports-search-filter',
  templateUrl: './my-reports-search-filter.component.html',
  styleUrls: ['./my-reports-search-filter.component.scss'],
  providers: [
    { provide: DateAdapter, useClass: AppDateAdapter },
    { provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS },
  ],
})
export class MyReportsSearchFilterComponent implements OnInit {
  @Input() filters: Partial<{
    state: string;
    date: string;
    customDateStart: Date;
    customDateEnd: Date;
    sortParam: string;
    sortDir: string;
  }>;

  fg: FormGroup;

  constructor(private fb: FormBuilder, private popoverController: PopoverController) {}

  ngOnInit() {
    this.fg = this.fb.group({
      state: [this.filters && this.filters.state],
      date: [this.filters && this.filters.date],
      customDateStart: [this.filters && this.filters.customDateStart],
      customDateEnd: [this.filters && this.filters.customDateEnd],
    });

    this.fg.validator = this.customDatevalidator;
  }

  customDatevalidator(formGroup: FormGroup) {
    if (
      formGroup.value.date &&
      formGroup.value.date === 'CUSTOMDATE' &&
      (formGroup.controls.customDateStart.value === null || formGroup.controls.customDateEnd.value === null)
    ) {
      return {
        error: 'custom date input is required when custom dates are selected',
      };
    }
  }

  save() {
    if (this.fg.value.date !== 'CUSTOMDATE') {
      this.fg.controls.customDateStart.reset();
      this.fg.controls.customDateEnd.reset();
    }

    this.popoverController.dismiss({
      filters: this.fg.value,
    });
  }

  cancel() {
    this.popoverController.dismiss();
  }

  clearAll() {
    this.fg.reset();
  }
}
Example #13
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 5 votes vote down vote up
describe('NgxDateFnsDateAdapter with NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS override', () => {
  describe('use UTC', () => {
    let adapter: NgxDateFnsDateAdapter;

    beforeEach(
      waitForAsync(() => {
        TestBed.configureTestingModule({
          imports: [NgxMatDateFnsDateModule],
          providers: [
            {
              provide: NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS,
              useValue: { useUtc: true },
            },
          ],
        }).compileComponents();
      })
    );

    beforeEach(inject([DateAdapter], (d: NgxDateFnsDateAdapter) => {
      adapter = d;
    }));

    it('should create date in UTC', () => {
      const expectedDate = parseJSON('2017-01-02T00:00:00Z');
      expect(adapter.createDate(2017, JAN, 2)).toEqual(expectedDate);
    });

    it('should create today in UTC', () => {
      const today = new Date();
      const todayUTCString = `${today.getFullYear()}-${(today.getMonth() + 1)
        .toString()
        .padStart(2, '0')}-${today
        .getDate()
        .toString()
        .padStart(2, '0')}T00:00:00Z`;
      const expectedDate = parseJSON(todayUTCString);
      expect(adapter.today()).toEqual(expectedDate);
    });

    it('should parse dates to UTC', () => {
      const expectedDate = parseJSON('2017-01-02T00:00:00Z');
      expect(adapter.parse('1/2/2017', 'MM/dd/yyyy')).toEqual(expectedDate);
    });

    it('should return UTC date when deserializing', () => {
      const expectedDate = parseJSON('2020-04-12T23:20:50.52Z');
      expect(adapter.deserialize('2020-04-12T23:20:50.52Z')).toEqual(
        expectedDate
      );
    });
  });
});
Example #14
Source File: corporate-card-expenses-search-filter.component.ts    From fyle-mobile-app with MIT License 5 votes vote down vote up
@Component({
  selector: 'app-corporate-card-expenses-search-filter',
  templateUrl: './corporate-card-expenses-search-filter.component.html',
  styleUrls: ['./corporate-card-expenses-search-filter.component.scss'],
  providers: [
    { provide: DateAdapter, useClass: AppDateAdapter },
    { provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS },
  ],
})
export class CorporateCardExpensesSearchFilterComponent implements OnInit {
  @Input() filters: Partial<{
    date: string;
    customDateStart: Date;
    customDateEnd: Date;
    sortParam: string;
    sortDir: string;
  }>;

  fg: FormGroup;

  constructor(private fb: FormBuilder, private popoverController: PopoverController) {}

  ngOnInit() {
    this.fg = this.fb.group({
      date: [this.filters && this.filters.date],
      customDateStart: [this.filters && this.filters.customDateStart],
      customDateEnd: [this.filters && this.filters.customDateEnd],
    });

    this.fg.validator = this.customDatevalidator;
  }

  customDatevalidator(formGroup: FormGroup) {
    if (
      formGroup.value.date &&
      formGroup.value.date === 'CUSTOMDATE' &&
      (formGroup.controls.customDateStart.value === null || formGroup.controls.customDateEnd.value === null)
    ) {
      return {
        error: 'custom date input is required when custom dates are selected',
      };
    }
  }

  save() {
    if (this.fg.value.date !== 'CUSTOMDATE') {
      this.fg.controls.customDateStart.reset();
      this.fg.controls.customDateEnd.reset();
    }

    this.popoverController.dismiss({
      filters: this.fg.value,
    });
  }

  cancel() {
    this.popoverController.dismiss();
  }

  clearAll() {
    this.fg.reset();
  }
}
Example #15
Source File: different-locale-datepicker.component.ts    From matx-angular with MIT License 5 votes vote down vote up
constructor(private adapter: DateAdapter<any>) {}
Example #16
Source File: date-adapter.ts    From ngx-mat-datetime-picker with MIT License 4 votes vote down vote up
export abstract class NgxMatDateAdapter<D> extends DateAdapter<D> {
  /**
 * Gets the hour component of the given date.
 * @param date The date to extract the month from.
 * @returns The hour component.
 */
  abstract getHour(date: D): number;

  /**
* Gets the minute component of the given date.
* @param date The date to extract the month from.
* @returns The minute component.
*/
  abstract getMinute(date: D): number;

  /**
  * Gets the second component of the given date.
  * @param date The date to extract the month from.
  * @returns The second component.
  */
  abstract getSecond(date: D): number;

  /**
  * Set the hour component of the given date.
  * @param date The date to extract the month from.
  * @param value The value to set.
  */
  abstract setHour(date: D, value: number): void;

  /**
  * Set the second component of the given date.
  * @param date The date to extract the month from.
  * @param value The value to set.
  */
  abstract setMinute(date: D, value: number): void;

  /**
   * Set the second component of the given date.
   * @param date The date to extract the month from.
   * @param value The value to set.
   */
  abstract setSecond(date: D, value: number): void;

  /**
   * Check if two date have same time
   * @param a Date 1
   * @param b Date 2
   */
  isSameTime(a: D, b: D): boolean {
    if (a == null || b == null) return true;
    return this.getHour(a) === this.getHour(b)
      && this.getMinute(a) === this.getMinute(b)
      && this.getSecond(a) === this.getSecond(b);
  }

  /**
   * Copy time from a date to a another date
   * @param toDate 
   * @param fromDate 
   */
  copyTime(toDate: D, fromDate: D) {
    this.setHour(toDate, this.getHour(fromDate));
    this.setMinute(toDate, this.getMinute(fromDate));
    this.setSecond(toDate, this.getSecond(fromDate));
  }

  /**
 * Compares two dates.
 * @param first The first date to compare.
 * @param second The second date to compare.
 * @returns 0 if the dates are equal, a number less than 0 if the first date is earlier,
 *     a number greater than 0 if the first date is later.
 */
  compareDateWithTime(first: D, second: D, showSeconds?: boolean): number {
    let res = super.compareDate(first, second) ||
      this.getHour(first) - this.getHour(second) ||
      this.getMinute(first) - this.getMinute(second);
    if (showSeconds) {
      res = res || this.getSecond(first) - this.getSecond(second);
    }
    return res;
  }

}
Example #17
Source File: ngx-mat-datefns-date-adapter.spec.ts    From ngx-mat-datefns-date-adapter with MIT License 4 votes vote down vote up
describe('NgxDateFnsDateAdapter', () => {
  let adapter: NgxDateFnsDateAdapter;
  let assertValidDate: (d: Date | null, valid: boolean) => void;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        imports: [NgxMatDateFnsDateModule],
      }).compileComponents();
    })
  );

  beforeEach(inject([DateAdapter], (dateAdapter: NgxDateFnsDateAdapter) => {
    adapter = dateAdapter;

    assertValidDate = (d: Date | null, valid: boolean) => {
      expect(adapter.isDateInstance(d)).not.toBeNull(
        `Expected ${d} to be a date instance`
      );
      expect(adapter.isValid(d as Date)).toBe(
        valid,
        `Expected ${d} to be ${valid ? 'valid' : 'invalid'},` +
          ` but was ${valid ? 'invalid' : 'valid'}`
      );
    };
  }));

  it('should get year', () => {
    expect(adapter.getYear(new Date(2017, JAN, 1))).toBe(2017);
  });

  it('should get month', () => {
    expect(adapter.getMonth(new Date(2017, JAN, 1))).toBe(0);
  });

  it('should get number of days in a month', () => {
    expect(adapter.getNumDaysInMonth(new Date(2017, JAN, 1))).toBe(31);
    expect(adapter.getNumDaysInMonth(new Date(2016, FEB, 1))).toBe(29);
  });

  it('should get date', () => {
    expect(adapter.getDate(new Date(2017, JAN, 1))).toBe(1);
  });

  it('should get day of week', () => {
    expect(adapter.getDayOfWeek(new Date(2017, JAN, 1))).toBe(0);
  });

  it('should get long month names', () => {
    expect(adapter.getMonthNames('long')).toEqual([
      'January',
      'February',
      'March',
      'April',
      'May',
      'June',
      'July',
      'August',
      'September',
      'October',
      'November',
      'December',
    ]);
  });

  it('should get short month names', () => {
    expect(adapter.getMonthNames('short')).toEqual([
      'Jan',
      'Feb',
      'Mar',
      'Apr',
      'May',
      'Jun',
      'Jul',
      'Aug',
      'Sep',
      'Oct',
      'Nov',
      'Dec',
    ]);
  });

  it('should get narrow month names', () => {
    expect(adapter.getMonthNames('narrow')).toEqual([
      'J',
      'F',
      'M',
      'A',
      'M',
      'J',
      'J',
      'A',
      'S',
      'O',
      'N',
      'D',
    ]);
  });

  it('should get month names in a different locale', () => {
    adapter.setLocale(ja);
    expect(adapter.getMonthNames('long')).toEqual([
      '1月',
      '2月',
      '3月',
      '4月',
      '5月',
      '6月',
      '7月',
      '8月',
      '9月',
      '10月',
      '11月',
      '12月',
    ]);
  });

  it('should get date names', () => {
    expect(adapter.getDateNames()).toEqual([
      '1',
      '2',
      '3',
      '4',
      '5',
      '6',
      '7',
      '8',
      '9',
      '10',
      '11',
      '12',
      '13',
      '14',
      '15',
      '16',
      '17',
      '18',
      '19',
      '20',
      '21',
      '22',
      '23',
      '24',
      '25',
      '26',
      '27',
      '28',
      '29',
      '30',
      '31',
    ]);
  });

  it('should get long day of week names', () => {
    expect(adapter.getDayOfWeekNames('long')).toEqual([
      'Sunday',
      'Monday',
      'Tuesday',
      'Wednesday',
      'Thursday',
      'Friday',
      'Saturday',
    ]);
  });

  it('should get short day of week names', () => {
    expect(adapter.getDayOfWeekNames('short')).toEqual([
      'Sun',
      'Mon',
      'Tue',
      'Wed',
      'Thu',
      'Fri',
      'Sat',
    ]);
  });

  it('should get narrow day of week names', () => {
    expect(adapter.getDayOfWeekNames('narrow')).toEqual([
      'S',
      'M',
      'T',
      'W',
      'T',
      'F',
      'S',
    ]);
  });

  it('should get day of week names in a different locale', () => {
    adapter.setLocale(ja);
    expect(adapter.getDayOfWeekNames('long')).toEqual([
      '日曜日',
      '月曜日',
      '火曜日',
      '水曜日',
      '木曜日',
      '金曜日',
      '土曜日',
    ]);
  });

  it('should get year name', () => {
    expect(adapter.getYearName(new Date(2017, JAN, 1))).toBe('2017');
  });

  it('should get first day of week', () => {
    expect(adapter.getFirstDayOfWeek()).toBe(0);
  });

  it('should create Date', () => {
    expect(adapter.createDate(2017, JAN, 1)).toEqual(new Date(2017, JAN, 1));
  });

  it('should not create Date with month over/under-flow', () => {
    expect(() => adapter.createDate(2017, DEC + 1, 1)).toThrow();
    expect(() => adapter.createDate(2017, JAN - 1, 1)).toThrow();
  });

  it('should not create Date with date over/under-flow', () => {
    expect(() => adapter.createDate(2017, JAN, 32)).toThrow();
    expect(() => adapter.createDate(2017, JAN, 0)).toThrow();
  });

  it('should create Date with low year number', () => {
    expect(adapter.createDate(-1, JAN, 1).getFullYear()).toBe(-1);
    expect(adapter.createDate(0, JAN, 1).getFullYear()).toBe(0);
    expect(adapter.createDate(50, JAN, 1).getFullYear()).toBe(50);
    expect(adapter.createDate(99, JAN, 1).getFullYear()).toBe(99);
    expect(adapter.createDate(100, JAN, 1).getFullYear()).toBe(100);
  });

  it("should get today's date", () => {
    expect(adapter.sameDate(adapter.today(), new Date())).toBe(
      true,
      "should be equal to today's date"
    );
  });

  it('should parse string', () => {
    expect(adapter.parse('1/1/2017', 'dd/MM/yyyy')).toEqual(
      new Date(2017, JAN, 1)
    );
  });

  it('should parse number', () => {
    const timestamp = new Date().getTime();
    expect(adapter.parse(timestamp, 'dd/MM/yyyy')).toEqual(new Date(timestamp));
  });

  it('should parse Date', () => {
    const date = new Date(2017, JAN, 1);
    expect(adapter.parse(date, 'dd/MM/yyyy')).toEqual(date);
    expect(adapter.parse(date, 'dd/MM/yyyy')).not.toBe(date);
  });

  it('should parse undefined as null', () => {
    expect(adapter.parse(undefined, 'dd/MM/yyyy')).toBeNull();
  });

  it('should parse [] as null', () => {
    expect(adapter.parse([], 'dd/MM/yyyy')).toBeNull();
  });

  it('should parse invalid value as invalid', () => {
    const d = adapter.parse('hello', 'dd/MM/yyyy');
    expect(d).not.toBeNull();
    expect(adapter.isDateInstance(d)).toBe(
      true,
      'Expected string to have been fed through Date.parse'
    );
    expect(adapter.isValid(d as Date)).toBe(
      false,
      'Expected to parse as "invalid date" object'
    );
  });

  it('should format', () => {
    expect(adapter.format(new Date(2017, JAN, 1), 'd/d/yyyy')).toEqual(
      '1/1/2017'
    );
  });

  it('should format with custom format', () => {
    expect(adapter.format(new Date(2017, JAN, 1), 'MMMM d, yyyy')).toEqual(
      'January 1, 2017'
    );
  });

  it('should format with a different locale', () => {
    adapter.setLocale(ja);
    expect(adapter.format(new Date(2017, JAN, 1), 'yyyy/d/d')).toEqual(
      '2017/1/1'
    );
  });

  it('should throw when attempting to format invalid date', () => {
    expect(() => adapter.format(new Date(NaN), 'd/d/yyyy')).toThrowError(
      /Invalid time value/
    );
  });

  it('should throw when attempting to set locale via string without providing NGX_MAT_DATEFNS_LOCALES token', () => {
    expect(() => adapter.setLocale('invalid')).toThrowError(
      /locale 'invalid' does not exist in locales array. Add it to the NGX_MAT_DATEFNS_LOCALES token./
    );
  });

  it('should throw when attempting to load null locale', () => {
    // @ts-expect-error - Argument of type 'Date | null' is not assignable to parameter of type 'Date'.
    expect(() => adapter.setLocale(null)).toThrowError(
      /setLocale should be called with the string locale code or date-fns Locale object/
    );
  });

  it('should add years', () => {
    expect(adapter.addCalendarYears(new Date(2017, JAN, 1), 1)).toEqual(
      new Date(2018, JAN, 1)
    );
    expect(adapter.addCalendarYears(new Date(2017, JAN, 1), -1)).toEqual(
      new Date(2016, JAN, 1)
    );
  });

  it('should respect leap years when adding years', () => {
    expect(adapter.addCalendarYears(new Date(2016, FEB, 29), 1)).toEqual(
      new Date(2017, FEB, 28)
    );
    expect(adapter.addCalendarYears(new Date(2016, FEB, 29), -1)).toEqual(
      new Date(2015, FEB, 28)
    );
  });

  it('should add months', () => {
    expect(adapter.addCalendarMonths(new Date(2017, JAN, 1), 1)).toEqual(
      new Date(2017, FEB, 1)
    );
    expect(adapter.addCalendarMonths(new Date(2017, JAN, 1), -1)).toEqual(
      new Date(2016, DEC, 1)
    );
  });

  it('should respect month length differences when adding months', () => {
    expect(adapter.addCalendarMonths(new Date(2017, JAN, 31), 1)).toEqual(
      new Date(2017, FEB, 28)
    );
    expect(adapter.addCalendarMonths(new Date(2017, MAR, 31), -1)).toEqual(
      new Date(2017, FEB, 28)
    );
  });

  it('should add days', () => {
    expect(adapter.addCalendarDays(new Date(2017, JAN, 1), 1)).toEqual(
      new Date(2017, JAN, 2)
    );
    expect(adapter.addCalendarDays(new Date(2017, JAN, 1), -1)).toEqual(
      new Date(2016, DEC, 31)
    );
  });

  it('should clone', () => {
    const date = new Date(2017, JAN, 1);
    expect(adapter.clone(date)).toEqual(date);
    expect(adapter.clone(date)).not.toBe(date);
  });

  it('should preserve time when cloning', () => {
    const date = new Date(2017, JAN, 1, 4, 5, 6);
    expect(adapter.clone(date)).toEqual(date);
    expect(adapter.clone(date)).not.toBe(date);
  });

  it('should compare dates', () => {
    expect(
      adapter.compareDate(new Date(2017, JAN, 1), new Date(2017, JAN, 2))
    ).toBeLessThan(0);
    expect(
      adapter.compareDate(new Date(2017, JAN, 1), new Date(2017, FEB, 1))
    ).toBeLessThan(0);
    expect(
      adapter.compareDate(new Date(2017, JAN, 1), new Date(2018, JAN, 1))
    ).toBeLessThan(0);
    expect(
      adapter.compareDate(new Date(2017, JAN, 1), new Date(2017, JAN, 1))
    ).toBe(0);
    expect(
      adapter.compareDate(new Date(2018, JAN, 1), new Date(2017, JAN, 1))
    ).toBeGreaterThan(0);
    expect(
      adapter.compareDate(new Date(2017, FEB, 1), new Date(2017, JAN, 1))
    ).toBeGreaterThan(0);
    expect(
      adapter.compareDate(new Date(2017, JAN, 2), new Date(2017, JAN, 1))
    ).toBeGreaterThan(0);
  });

  it('should clamp date at lower bound', () => {
    expect(
      adapter.clampDate(
        new Date(2017, JAN, 1),
        new Date(2018, JAN, 1),
        new Date(2019, JAN, 1)
      )
    ).toEqual(new Date(2018, JAN, 1));
  });

  it('should clamp date at upper bound', () => {
    expect(
      adapter.clampDate(
        new Date(2020, JAN, 1),
        new Date(2018, JAN, 1),
        new Date(2019, JAN, 1)
      )
    ).toEqual(new Date(2019, JAN, 1));
  });

  it('should clamp date already within bounds', () => {
    expect(
      adapter.clampDate(
        new Date(2018, FEB, 1),
        new Date(2018, JAN, 1),
        new Date(2019, JAN, 1)
      )
    ).toEqual(new Date(2018, FEB, 1));
  });

  it('should use UTC for formatting by default', () => {
    expect(adapter.format(new Date(1800, 7, 14), 'E MMM dd yyyy')).toBe(
      'Thu Aug 14 1800'
    );
  });

  it('should count today as a valid date instance', () => {
    const d = new Date();
    expect(adapter.isValid(d)).toBe(true);
    expect(adapter.isDateInstance(d)).toBe(true);
  });

  it('should count an invalid date as an invalid date instance', () => {
    const d = new Date(NaN);
    expect(adapter.isValid(d)).toBe(false);
    expect(adapter.isDateInstance(d)).toBe(true);
  });

  it('should count a string as not a date instance', () => {
    const d = '1/1/2017';
    expect(adapter.isDateInstance(d)).toBe(false);
  });

  it('should create dates from valid ISO strings', () => {
    assertValidDate(adapter.deserialize('1985-04-12T23:20:50.52Z'), true);
    assertValidDate(adapter.deserialize('1996-12-19T16:39:57-08:00'), true);
    assertValidDate(adapter.deserialize('1937-01-01T12:00:27.87+00:20'), true);
    assertValidDate(adapter.deserialize('2017-01-01'), true);
    assertValidDate(adapter.deserialize('2017-01-01T00:00:00'), true);
    assertValidDate(adapter.deserialize('1990-13-31T23:59:00Z'), false);
    assertValidDate(adapter.deserialize('1/1/2017'), false);
    assertValidDate(adapter.deserialize('2017-01-01T'), true);
    assertValidDate(adapter.deserialize(1483228800), true);
    expect(adapter.deserialize('')).toBeNull();
    expect(adapter.deserialize(null)).toBeNull();
    expect(adapter.deserialize([])).toBeNull();
    assertValidDate(adapter.deserialize(new Date()), true);
    assertValidDate(adapter.deserialize(new Date(NaN)), false);
    assertValidDate(adapter.deserialize(1483228800), true);
  });

  it('should format Date to ISO8601 string', () => {
    expect(adapter.toIso8601(new Date(2017, JAN, 1))).toEqual(
      new Date(2017, JAN, 1).toISOString()
    );
  });

  it('should create an invalid date', () => {
    assertValidDate(adapter.invalid(), false);
  });

  it('should not throw when attempting to format a date with a year less than 1', () => {
    expect(() => adapter.format(new Date(-1, 1, 1), 'd/d/yyyy')).not.toThrow();
  });

  it('should not throw when attempting to format a date with a year greater than 9999', () => {
    expect(() =>
      adapter.format(new Date(10000, 1, 1), 'd/d/yyyy')
    ).not.toThrow();
  });
});
Example #18
Source File: dxc-date-input.component.spec.ts    From halstack-angular with Apache License 2.0 4 votes vote down vote up
describe("DxcDate", () => {
  const newMockDate = new Date("1995/12/03");
  const newValue = "03-12-1995";

  test("should render dxc-date", async () => {
    const { getByText } = await render(DxcDateInputComponent, {
      componentProperties: { label: "test-date" },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });

    expect(getByText("test-date"));
  });

  test("The input´s value is the same as the one received as a parameter", async () => {
    const onChange = jest.fn();
    const onBlur = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        value: "03-12-1995",
        onChange: {
          emit: onChange,
        } as any,
        onBlur: {
          emit: onBlur,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });

    const input = <HTMLInputElement>screen.getByRole("textbox");
    const calendarIcon = screen.getByRole("calendarIcon");

    input.focus();
    expect(screen.getByDisplayValue("03-12-1995"));
    fireEvent.click(calendarIcon);
    expect(screen.getByText("DECEMBER 1995"));
    expect(
      screen.getByText("3").classList.contains("mat-calendar-body-selected")
    ).toBeTruthy();
  });

  test("dxc-date value change and default format", async () => {
    const onChange = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        onChange: {
          emit: onChange,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });

    const input = <HTMLInputElement>screen.getByRole("textbox");
    input.focus();
    fireEvent.input(input, { target: { value: newValue } });
    expect(onChange).toHaveBeenCalledWith({
      value: newValue,
      error: undefined,
      date: newMockDate,
    });
    expect(screen.getByDisplayValue(newValue));
  });

  test("dxc-date change value twice as uncontrolled", async () => {
    const onChange = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        defaultValue: "22-10-1998",
        onChange: {
          emit: onChange,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });
    expect(screen.getByDisplayValue("22-10-1998"));
    const input = <HTMLInputElement>screen.getByRole("textbox");
    input.focus();
    fireEvent.input(input, { target: { value: newValue } });
    expect(onChange).toHaveBeenCalledWith({
      value: newValue,
      error: undefined,
      date: newMockDate,
    });
    expect(screen.getByDisplayValue(newValue));

    input.focus();
    fireEvent.input(input, { target: { value: "04-10-1996" } });
    expect(onChange).toHaveBeenCalledWith({
      value: "04-10-1996",
      error: undefined,
      date: new Date("1996/10/04"),
    });
    expect(screen.getByDisplayValue("04-10-1996"));
  });

  test("Calendar´s value is the same as the input´s date if it´s right (Depending on the format)", async () => {
    const onChange = jest.fn();
    const onBlur = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        format: "YYYY/MM/DD",
        onChange: {
          emit: onChange,
        } as any,
        onBlur: {
          emit: onBlur,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });

    const input = <HTMLInputElement>screen.getByRole("textbox");
    const calendarIcon = screen.getByRole("calendarIcon");

    input.focus();
    fireEvent.input(input, { target: { value: "1995/12/03" } });
    expect(onChange).toHaveBeenCalledWith({
      value: "1995/12/03",
      error: undefined,
      date: newMockDate,
    });
    input.focus();
    expect(screen.getByDisplayValue("1995/12/03"));
    fireEvent.click(calendarIcon);
    waitFor(() => {
      expect(screen.getByText("DECEMBER 1995"));
    });
    waitFor(() => {
      expect(
        screen.getByText("3").classList.contains("mat-calendar-body-selected")
      ).toBeTruthy();
    });
  });

  test("dxc-date invalid value", async () => {
    const onChange = jest.fn();
    const invalidValue = "03-12-199_";

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        onChange: {
          emit: onChange,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });
    const input = <HTMLInputElement>screen.getByRole("textbox");

    input.focus();
    fireEvent.input(input, { target: { value: invalidValue } });

    expect(onChange).toHaveBeenCalledWith({
      value: invalidValue,
      error: undefined,
      date: undefined,
    });
  });

  test("onChange function is called when the user selects from the calendar", async () => {
    const onChange = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        value: newValue,
        onChange: {
          emit: onChange,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });
    const calendarIcon = screen.getByRole("calendarIcon");

    fireEvent.click(calendarIcon);
    fireEvent.click(screen.getByText("4"));
    waitFor(() => {
      expect(onChange).toHaveBeenCalledWith({
        value: "04-12-1995",
        date: new Date("04/12/1995"),
      });
    });
  });

  test("onChange function is called when the user selects from the calendar, the stringValue received by the function is the date with the correct format", async () => {
    const onChange = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        value: "12-03-1995",
        format: "MM-DD-YYYY",
        onChange: {
          emit: onChange,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });
    const calendarIcon = screen.getByRole("calendarIcon");

    fireEvent.click(calendarIcon);
    expect(screen.getByText("DECEMBER 1995"));
    expect(
      screen.getByText("3").classList.contains("mat-calendar-body-selected")
    ).toBeTruthy();
    fireEvent.click(screen.getByText("4"));
    waitFor(() => {
      expect(onChange).toHaveBeenCalledWith({
        value: "12-04-1995",
        date: new Date("04/12/1995"),
      });
    });
  });

  test("If the user types something, if controlled and without onChange, the value doesn´t change", async () => {
    const onChange = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        value: newValue,
        onChange: {
          emit: onChange,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });
    const calendarIcon = screen.getByRole("calendarIcon");

    fireEvent.click(calendarIcon);
    expect(screen.getByText("DECEMBER 1995"));
    expect(
      screen.getByText("3").classList.contains("mat-calendar-body-selected")
    ).toBeTruthy();
    fireEvent.click(screen.getByText("4"));
    waitFor(() => {
      expect(onChange).toHaveBeenCalledWith({
        value: "04-12-1995",
        date: new Date("04/12/1995"),
      });
    });

    fireEvent.click(calendarIcon);

    expect(screen.getByText("DECEMBER 1995"));
    waitFor(() => {
      expect(
        screen.getByText("3").classList.contains("mat-calendar-body-selected")
      ).toBeTruthy();
    });
  });

  test("controlled dxc-date", async () => {
    const onChange = jest.fn();
    const onBlur = jest.fn();

    await render(DxcDateInputComponent, {
      componentProperties: {
        label: "test-input",
        value: "03-12-1995",
        defaultValue: "12-04-1995",
        onChange: {
          emit: onChange,
        } as any,
        onBlur: {
          emit: onBlur,
        } as any,
      },
      imports: [
        MatDayjsDateModule,
        MatNativeDateModule,
        MatInputModule,
        MatDatepickerModule,
        MdePopoverModule,
        DxcBoxModule,
        CommonModule,
        DxcTextInputModule,
      ],
      providers: [
        { provide: MAT_DATE_FORMATS, useValue: DAYJS_DATE_FORMATS },
        {
          provide: DateAdapter,
          useClass: DayjsDateAdapter,
          deps: [MAT_DATE_LOCALE, Platform],
        },
      ],
    });
    expect(screen.getByDisplayValue("03-12-1995"));
    const input = <HTMLInputElement>screen.getByRole("textbox");

    input.focus();
    fireEvent.input(input, { target: { value: "03-10-1996" } });
    expect(onChange).toHaveBeenCalledWith({
      value: "03-10-1996",
      error: undefined,
      date: new Date("1996/10/03"),
    });
    expect(screen.getByDisplayValue("03-12-1995"));
    fireEvent.blur(input);
    waitFor(() => {
      expect(onBlur).toHaveBeenCalledWith({
        error: undefined,
        value: "03-12-1995",
        date: new Date("1995/12/03"),
      });
    });
  });
});
Example #19
Source File: date-adapter.ts    From angular-material-components with MIT License 4 votes vote down vote up
export abstract class NgxMatDateAdapter<D> extends DateAdapter<D> {
  /**
 * Gets the hour component of the given date.
 * @param date The date to extract the month from.
 * @returns The hour component.
 */
  abstract getHour(date: D): number;

  /**
* Gets the minute component of the given date.
* @param date The date to extract the month from.
* @returns The minute component.
*/
  abstract getMinute(date: D): number;

  /**
  * Gets the second component of the given date.
  * @param date The date to extract the month from.
  * @returns The second component.
  */
  abstract getSecond(date: D): number;

  /**
  * Set the hour component of the given date.
  * @param date The date to extract the month from.
  * @param value The value to set.
  */
  abstract setHour(date: D, value: number): void;

  /**
  * Set the second component of the given date.
  * @param date The date to extract the month from.
  * @param value The value to set.
  */
  abstract setMinute(date: D, value: number): void;

  /**
   * Set the second component of the given date.
   * @param date The date to extract the month from.
   * @param value The value to set.
   */
  abstract setSecond(date: D, value: number): void;

  /**
   * Check if two date have same time
   * @param a Date 1
   * @param b Date 2
   */
  isSameTime(a: D, b: D): boolean {
    if (a == null || b == null) return true;
    return this.getHour(a) === this.getHour(b)
      && this.getMinute(a) === this.getMinute(b)
      && this.getSecond(a) === this.getSecond(b);
  }

  /**
   * Copy time from a date to a another date
   * @param toDate 
   * @param fromDate 
   */
  copyTime(toDate: D, fromDate: D) {
    this.setHour(toDate, this.getHour(fromDate));
    this.setMinute(toDate, this.getMinute(fromDate));
    this.setSecond(toDate, this.getSecond(fromDate));
  }

  /**
 * Compares two dates.
 * @param first The first date to compare.
 * @param second The second date to compare.
 * @returns 0 if the dates are equal, a number less than 0 if the first date is earlier,
 *     a number greater than 0 if the first date is later.
 */
  compareDateWithTime(first: D, second: D, showSeconds?: boolean): number {
    let res = super.compareDate(first, second) ||
      this.getHour(first) - this.getHour(second) ||
      this.getMinute(first) - this.getMinute(second);
    if (showSeconds) {
      res = res || this.getSecond(first) - this.getSecond(second);
    }
    return res;
  }

  /**
   * Set time by using default values
   * @param defaultTime List default values [hour, minute, second]
   */
  setTimeByDefaultValues(date: D, defaultTime: number[]) {
    if (!Array.isArray(defaultTime)) {
      throw Error('@Input DefaultTime should be an array');
    }
    this.setHour(date, defaultTime[0] || 0);
    this.setMinute(date, defaultTime[1] || 0);
    this.setSecond(date, defaultTime[2] || 0);
  }

}
Example #20
Source File: wizard-field.component.ts    From geonetwork-ui with GNU General Public License v2.0 4 votes vote down vote up
@Component({
  selector: 'gn-ui-wizard-field',
  templateUrl: './wizard-field.component.html',
  styleUrls: ['./wizard-field.component.css'],
  providers: [
    { provide: MAT_DATE_LOCALE, useValue: getLangFromBrowser() },
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
    },
    { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
  ],
})
export class WizardFieldComponent implements AfterViewInit, OnDestroy {
  @Input() wizardFieldConfig: WizardFieldModel

  @ViewChild('searchText') searchText: TextInputComponent
  @ViewChild('chips') chips: ChipsInputComponent
  @ViewChild('textArea') textArea: TextAreaComponent
  @ViewChild('dropdown') dropdown: DropdownSelectorComponent

  subs = new Subscription()

  get wizardFieldType(): typeof WizardFieldType {
    return WizardFieldType
  }

  get dropdownChoices(): any {
    return this.wizardFieldConfig.options
  }

  get wizardFieldData() {
    const data = this.wizardService.getWizardFieldData(
      this.wizardFieldConfig.id
    )
    switch (this.wizardFieldConfig.type) {
      case WizardFieldType.TEXT: {
        return data || ''
      }
      case WizardFieldType.CHIPS: {
        return data ? JSON.parse(data) : []
      }
      case WizardFieldType.TEXT_AREA: {
        return data || ''
      }
      case WizardFieldType.DATA_PICKER: {
        return data ? new Date(Number(data)) : new Date()
      }
      case WizardFieldType.DROPDOWN: {
        return data ? JSON.parse(data) : this.dropdownChoices[1]
      }
    }
  }

  constructor(private wizardService: WizardService) {}

  ngAfterViewInit() {
    this.initializeListeners()
  }

  ngOnDestroy() {
    this.subs.unsubscribe()
  }

  private initializeListeners() {
    switch (this.wizardFieldConfig.type) {
      case WizardFieldType.TEXT: {
        this.initializeTextInputListener()
        break
      }
      case WizardFieldType.CHIPS: {
        this.initializeChipsListener()
        break
      }
      case WizardFieldType.TEXT_AREA: {
        this.initializeTextAreaListener()
        return
      }
      case WizardFieldType.DATA_PICKER: {
        this.initializeDateInput()
        return
      }
      case WizardFieldType.DROPDOWN: {
        this.initializeDropdownListener()
        return
      }
    }
  }

  private initializeTextInputListener() {
    this.subs.add(
      this.searchText.valueChange.subscribe((value) => {
        this.wizardService.onWizardWizardFieldDataChanged(
          this.wizardFieldConfig.id,
          value
        )
      })
    )
  }

  private initializeChipsListener() {
    this.subs.add(
      this.chips.itemsChange.subscribe((items) => {
        this.wizardService.onWizardWizardFieldDataChanged(
          this.wizardFieldConfig.id,
          JSON.stringify(items)
        )
      })
    )
  }

  private initializeTextAreaListener() {
    this.subs.add(
      this.textArea.valueChange.subscribe((value) => {
        this.wizardService.onWizardWizardFieldDataChanged(
          this.wizardFieldConfig.id,
          value
        )
      })
    )
  }

  initializeDateInput() {
    const time = this.wizardService.getWizardFieldData(
      this.wizardFieldConfig.id
    )
    if (!time) {
      this.wizardService.onWizardWizardFieldDataChanged(
        this.wizardFieldConfig.id,
        new Date().valueOf()
      )
    }
  }

  onDateChange(event: MatDatepickerInputEvent<Date>) {
    this.wizardService.onWizardWizardFieldDataChanged(
      this.wizardFieldConfig.id,
      event.value.valueOf()
    )
  }

  private initializeDropdownListener() {
    this.subs.add(
      this.dropdown.selectValue.subscribe((value) => {
        this.wizardService.onWizardWizardFieldDataChanged(
          this.wizardFieldConfig.id,
          value
        )
      })
    )
  }
}
Example #21
Source File: ngx-mat-datefns-date-adapter.ts    From ngx-mat-datefns-date-adapter with MIT License 4 votes vote down vote up
@Injectable()
export class NgxDateFnsDateAdapter extends DateAdapter<Date> {
  private _dateFnsLocale!: Locale;
  private getLocale = (localeCodeOrLocale: string | Locale): Locale => {
    if (localeCodeOrLocale && (localeCodeOrLocale as Locale).code) {
      return localeCodeOrLocale as Locale;
    }
    if (!this.locales || !this.locales.length) {
      throw new Error('locales array does not provided or is empty. Provide it via the NGX_MAT_DATEFNS_LOCALES token.');
    }
    const locale = this.locales.find(
      (item) => item.code === localeCodeOrLocale
    );
    if (!locale) {
      throw new Error(`locale '${localeCodeOrLocale}' does not exist in locales array. Add it to the NGX_MAT_DATEFNS_LOCALES token.`);
    }
    return locale;
  };

  constructor(
    @Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string | null,
    @Optional() @Inject(NGX_MAT_DATEFNS_LOCALES) private locales: Locale[] | null,
    @Optional()
    @Inject(NGX_MAT_DATEFNS_DATE_ADAPTER_OPTIONS)
    private options?: NgxDateFnsDateAdapterOptions
  ) {
    super();

    if (!this.locales || this.locales.length === 0) {
      this.locales = [enUS];
    }

    try {
      this.setLocale(dateLocale || enUS);
    } catch (err) {
      this.setLocale(enUS);
    }
  }

  setLocale(locale: string | Locale) {
    if (!locale) {
      throw new Error(
        'setLocale should be called with the string locale code or date-fns Locale object'
      );
    }
    this._dateFnsLocale = this.getLocale(locale);
    super.setLocale(locale);
  }

  addCalendarDays(date: Date, days: number): Date {
    return addDays(date, days);
  }

  addCalendarMonths(date: Date, months: number): Date {
    return addMonths(date, months);
  }

  addCalendarYears(date: Date, years: number): Date {
    return addYears(date, years);
  }

  clone(date: Date): Date {
    return toDate(date);
  }

  createDate(year: number, month: number, date: number): Date {
    // Check for invalid month and date (except upper bound on date which we have to check after
    // creating the Date).
    if (month < 0 || month > 11) {
      throw Error(
        `Invalid month index "${month}". Month index has to be between 0 and 11.`
      );
    }

    if (date < 1) {
      throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
    }

    const result = this._createDateWithOverflow(year, month, date);
    // Check that the date wasn't above the upper bound for the month, causing the month to overflow
    if (result.getMonth() !== month) {
      throw Error(`Invalid date "${date}" for month with index "${month}".`);
    }

    return result;
  }

  deserialize(value: any): Date | null {
    if (value) {
      if (typeof value === 'string') {
        if (this.options?.useUtc) {
          return parseJSON(value);
        }
        return parseISO(value);
      }
      if (typeof value === 'number') {
        return toDate(value);
      }
      if (value instanceof Date) {
        return this.clone(value as Date);
      }
      return null;
    }
    return null;
  }

  format(date: Date, displayFormat: string): string {
    return format(date, displayFormat, { locale: this._dateFnsLocale });
  }

  getDate(date: Date): number {
    return getDate(date);
  }

  getDateNames(): string[] {
    return range(1, 31).map((day) => String(day));
  }

  getDayOfWeek(date: Date): number {
    return getDay(date);
  }

  getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[] {
    const map = {
      long: 'EEEE',
      short: 'EEE',
      narrow: 'EEEEE',
    };

    const formatStr = map[style];
    const date = new Date();

    return range(0, 6).map((day) =>
      format(setDay(date, day), formatStr, {
        locale: this._dateFnsLocale,
      })
    );
  }

  getFirstDayOfWeek(): number {
    return this._dateFnsLocale.options?.weekStartsOn ?? 0;
  }

  getMonth(date: Date): number {
    return getMonth(date);
  }

  getMonthNames(style: 'long' | 'short' | 'narrow'): string[] {
    const map = {
      long: 'LLLL',
      short: 'LLL',
      narrow: 'LLLLL',
    };

    const formatStr = map[style];
    const date = new Date();

    return range(0, 11).map((month) =>
      format(setMonth(date, month), formatStr, {
        locale: this._dateFnsLocale,
      })
    );
  }

  getNumDaysInMonth(date: Date): number {
    return getDaysInMonth(date);
  }

  getYear(date: Date): number {
    return getYear(date);
  }

  getYearName(date: Date): string {
    return format(date, 'yyyy', {
      locale: this._dateFnsLocale,
    });
  }

  invalid(): Date {
    return new Date(NaN);
  }

  isDateInstance(obj: any): boolean {
    return obj instanceof Date;
  }

  isValid(date: Date): boolean {
    return date instanceof Date && !isNaN(date.getTime());
  }

  parse(value: any, parseFormat: any): Date | null {
    if (value) {
      if (typeof value === 'string') {
        if (this.options?.useUtc) {
          const d = parse(value.trim(), parseFormat, new Date(), {
            locale: this._dateFnsLocale,
          });
          return zonedTimeToUtc(d, UTC_TIMEZONE);
        }
        return parse(value.trim(), parseFormat, new Date(), {
          locale: this._dateFnsLocale,
        });
      }
      if (typeof value === 'number') {
        return toDate(value);
      }
      if (value instanceof Date) {
        return this.clone(value as Date);
      }
      return null;
    }
    return null;
  }

  toIso8601(date: Date): string {
    return date.toISOString();
  }

  today(): Date {
    const d = new Date();
    return this._createDateWithOverflow(
      d.getFullYear(),
      d.getMonth(),
      d.getDate()
    );
  }

  /** Creates a date but allows the month and date to overflow. */
  private _createDateWithOverflow(year: number, month: number, date: number) {
    const result = this._createDateInternal(year, month, date);

    // We need to correct for the fact that JS native Date treats years in range [0, 99] as
    // abbreviations for 19xx.
    if (year >= 0 && year < 100) {
      result.setFullYear(this.getYear(result) - 1900);
    }
    return result;
  }

  private _createDateInternal(year: number, month: number, date: number): Date {
    if (this.options?.useUtc) {
      return zonedTimeToUtc(new Date(year, month, date), UTC_TIMEZONE);
    }
    return new Date(year, month, date);
  }
}
Example #22
Source File: date-functions.ts    From halstack-angular with Apache License 2.0 4 votes vote down vote up
/** Adapts dayjs Dates for use with Angular Material. */
@Injectable()
export class DayjsDateAdapter extends DateAdapter<dayjs.Dayjs> {
  // Note: all of the methods that accept a `dayjs` input parameter immediately call `this.clone`
  // on it. This is to ensure that we're working with a `dayjs` that has the correct locale setting
  // while avoiding mutating the original object passed to us. Just calling `.locale(...)` on the
  // input would mutate the object.

  private _localeData: {
    firstDayOfWeek: number;
    longMonths: string[];
    shortMonths: string[];
    dates: string[];
    longDaysOfWeek: string[];
    shortDaysOfWeek: string[];
    narrowDaysOfWeek: string[];
  };

  constructor(
    @Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string,
    @Optional()
    @Inject(DAYJS_DATE_ADAPTER_OPTIONS)
    private options?: DayjsDateAdapterOptions
  ) {
    super();
    dayjs.extend(localizedFormat);
    dayjs.extend(customParseFormat);
    dayjs.extend(localeData);
    dayjs.extend(relativeTime);

    this.setLocale(dateLocale);
  }

  setLocale(dateLocale: string): void {
    super.setLocale(dateLocale);

    const dayJsLocaleData = dayjs().localeData();
    this._localeData = {
      firstDayOfWeek: 0,
      longMonths: dayJsLocaleData.months(),
      shortMonths: dayJsLocaleData.monthsShort(),
      dates: range(31, (i) => this.createDate(2017, 0, i + 1).format("D")),
      longDaysOfWeek: dayJsLocaleData.weekdays(),
      shortDaysOfWeek: dayJsLocaleData.weekdaysShort(),
      narrowDaysOfWeek: dayJsLocaleData.weekdaysMin(),
    };
  }

  getYear(date: dayjs.Dayjs): number {
    return this.clone(date).year();
  }

  getMonth(date: dayjs.Dayjs): number {
    return this.clone(date).month();
  }

  getDate(date: dayjs.Dayjs): number {
    return this.clone(date).date();
  }

  getDayOfWeek(date: dayjs.Dayjs): number {
    return this.clone(date).day();
  }

  getMonthNames(style: "long" | "short" | "narrow"): string[] {
    // dayjs.js doesn't support narrow month names, so we just use short if narrow is requested.
    return style === "long"
      ? this._localeData.longMonths
      : this._localeData.shortMonths;
  }

  getDateNames(): string[] {
    return this._localeData.dates;
  }

  getDayOfWeekNames(style: "long" | "short" | "narrow"): string[] {
    if (style === "long") {
      return this._localeData.longDaysOfWeek;
    }
    if (style === "short") {
      return this._localeData.shortDaysOfWeek;
    }
    return this._localeData.narrowDaysOfWeek;
  }

  getYearName(date: dayjs.Dayjs): string {
    return this.clone(date).format("YYYY");
  }

  getFirstDayOfWeek(): number {
    return this._localeData.firstDayOfWeek;
  }

  getNumDaysInMonth(date: dayjs.Dayjs): number {
    return this.clone(date).daysInMonth();
  }

  clone(date: dayjs.Dayjs, format?: string): dayjs.Dayjs {
    return format ? dayjs(dayjs(date, format)) : date.clone();
  }

  new(date = undefined, format = undefined): dayjs.Dayjs {
    if (!date) {
      return dayjs();
    }
    if (format) {
      return dayjs(date, format);
    } else {
      return dayjs(date);
    }
  }

  createDate(year: number, month: number, date: number): dayjs.Dayjs {
    // dayjs.js will create an invalid date if any of the components are out of bounds, but we
    // explicitly check each case so we can throw more descriptive errors.
    if (month < 0 || month > 11) {
      throw Error(
        `Invalid month index "${month}". Month index has to be between 0 and 11.`
      );
    }
    if (date < 1) {
      throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
    }
    const result = this._createDayjs({ year, month, date });
    // If the result isn't valid, the date must have been out of bounds for this month.
    if (!result.isValid()) {
      throw Error(`Invalid date "${date}" for month with index "${month}".`);
    }
    return result;
  }

  today(): dayjs.Dayjs {
    return this._createDayjs();
  }

  parse(value: any): dayjs.Dayjs | null {
    if (value && typeof value === "string") {
      return this._createDayjs(value);
    }
    return value ? this._createDayjs(value) : null;
  }

  format(date: dayjs.Dayjs, displayFormat: string): string {
    date = this.clone(date);
    if (!this.isValid(date)) {
      throw Error("DayjsDateAdapter: Cannot format invalid date.");
    }
    return date.format(displayFormat);
  }

  addCalendarYears(date: dayjs.Dayjs, years: number): dayjs.Dayjs {
    return this.clone(date).add(years, "year");
  }

  addCalendarMonths(date: dayjs.Dayjs, months: number): dayjs.Dayjs {
    return this.clone(date).add(months, "month");
  }

  addCalendarDays(date: dayjs.Dayjs, days: number): dayjs.Dayjs {
    return this.clone(date).add(days, "day");
  }

  toIso8601(date: dayjs.Dayjs): string {
    return this.clone(date).toISOString();
  }

  /**
   * Returns the given value if given a valid dayjs or null. Deserializes valid ISO 8601 strings
   * (https://www.ietf.org/rfc/rfc3339.txt) and valid Date objects into valid dayjss and empty
   * string into null. Returns an invalid date for all other values.
   */
  deserialize(value: any): dayjs.Dayjs | null {
    let date;
    if (value instanceof Date) {
      date = this._createDayjs(value).locale(this.locale);
    } else if (this.isDateInstance(value)) {
      // Note: assumes that cloning also sets the correct locale.
      return this.clone(dayjs(value, "DD/MM/YYYY"));
    }
    if (typeof value === "string") {
      if (!value) {
        return null;
      }
      date = this._createDayjs(value).locale(this.locale);
    }
    if (date && this.isValid(date)) {
      return this._createDayjs(date).locale(this.locale);
    }
    return super.deserialize(value);
  }

  isDateInstance(obj: any): boolean {
    return dayjs.isDayjs(obj);
  }

  isValid(date: dayjs.Dayjs): boolean {
    return this.clone(date).isValid();
  }

  invalid(): dayjs.Dayjs {
    return dayjs(null);
  }

  /** Creates a dayjs instance */
  private _createDayjs(args?: any): dayjs.Dayjs {
    if (dayjs.isDayjs(args)) {
      return this.clone(args);
    } else if (args instanceof Date) {
      return this.clone(dayjs(args));
    } else {
      let djs = dayjs();
      let key: any;
      for (key in args) {
        if (args.hasOwnProperty(key)) {
          djs = djs.set(key, args[key]);
        }
      }
      return this.clone(djs, "DD/MM/YYYY");
    }
  }
}