mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(moment-date-adapter): implement strict mode (#16462)
* feat(moment-date-adapter): implement strict mode Moment supports a strict flag which solves a lot of parsing errors. Examples: | Input | Format | Forgiving | Strict | |-----------------|--------------|------------|--------------| | 1/2/2017 | M/D/YYYY | 2017-01-02 | 2017-01-02 | | 1/2/2017 | MM/DD/YYYY | 2017-01-02 | Invalid date | | Januari 1, 2017 | MMMM D, YYYY | 2017-01-01 | Invalid date | | Jan 1, 2017 | MMMM D, YYYY | 2017-01-01 | Invalid date | | 2017-1-1 | MMMM D, YYYY | 2017-01-20 | Invalid date | * docs(datepicker): remove spaces in useUtc example * refactor(moment-date-adapter): change toEqual -> ToBe in strict mode boolean tests * refactor(moment-date-adapter): destructure options useUtc has been made optional to prevent the necessity for default values. * docs(datepicker): remove spaces around strict example braces * docs(datepicker): add links to Moment's strict/forgiving mode
This commit is contained in:
committed by
mmalerba
parent
8658c30481
commit
dd4295608a
@@ -463,4 +463,39 @@ describe('MomentDateAdapter with MAT_MOMENT_DATE_ADAPTER_OPTIONS override', () =
|
||||
});
|
||||
});
|
||||
|
||||
describe('strict mode', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.resetTestingModule();
|
||||
TestBed.configureTestingModule({
|
||||
imports: [MomentDateModule],
|
||||
providers: [
|
||||
{
|
||||
provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS,
|
||||
useValue: {
|
||||
strict: true,
|
||||
},
|
||||
},
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(inject([DateAdapter], (d: MomentDateAdapter) => {
|
||||
adapter = d;
|
||||
}));
|
||||
|
||||
it('should detect valid strings according to given format', () => {
|
||||
expect(adapter.parse('1/2/2017', 'D/M/YYYY')!.format('l'))
|
||||
.toEqual(moment([2017, FEB, 1]).format('l'));
|
||||
expect(adapter.parse('February 1, 2017', 'MMMM D, YYYY')!.format('l'))
|
||||
.toEqual(moment([2017, FEB, 1]).format('l'));
|
||||
});
|
||||
|
||||
it('should detect invalid strings according to given format', () => {
|
||||
expect(adapter.parse('2017-01-01', 'MM/DD/YYYY')!.isValid()).toBe(false);
|
||||
expect(adapter.parse('1/2/2017', 'MM/DD/YYYY')!.isValid()).toBe(false);
|
||||
expect(adapter.parse('Jan 5, 2017', 'MMMM D, YYYY')!.isValid()).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,18 +15,25 @@ import {DateAdapter, MAT_DATE_LOCALE} from '@angular/material/core';
|
||||
// TODO(mmalerba): See if we can clean this up at some point.
|
||||
import * as _moment from 'moment';
|
||||
// tslint:disable-next-line:no-duplicate-imports
|
||||
import {default as _rollupMoment, Moment} from 'moment';
|
||||
import {default as _rollupMoment, Moment, MomentFormatSpecification, MomentInput} from 'moment';
|
||||
|
||||
const moment = _rollupMoment || _moment;
|
||||
|
||||
/** Configurable options for {@see MomentDateAdapter}. */
|
||||
export interface MatMomentDateAdapterOptions {
|
||||
|
||||
/**
|
||||
* When enabled, the dates have to match the format exactly.
|
||||
* See https://momentjs.com/guides/#/parsing/strict-mode/.
|
||||
*/
|
||||
strict?: boolean;
|
||||
|
||||
/**
|
||||
* Turns the use of utc dates on or off.
|
||||
* Changing this will change how Angular Material components like DatePicker output dates.
|
||||
* {@default false}
|
||||
*/
|
||||
useUtc: boolean;
|
||||
useUtc?: boolean;
|
||||
}
|
||||
|
||||
/** InjectionToken for moment date adapter to configure options. */
|
||||
@@ -241,7 +248,15 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
|
||||
}
|
||||
|
||||
/** Creates a Moment instance while respecting the current UTC settings. */
|
||||
private _createMoment(...args: any[]): Moment {
|
||||
return (this._options && this._options.useUtc) ? moment.utc(...args) : moment(...args);
|
||||
private _createMoment(
|
||||
date: MomentInput,
|
||||
format?: MomentFormatSpecification,
|
||||
locale?: string,
|
||||
): Moment {
|
||||
const {strict, useUtc}: MatMomentDateAdapterOptions = this._options || {};
|
||||
|
||||
return useUtc
|
||||
? moment.utc(date, format, locale, strict)
|
||||
: moment(date, format, locale, strict);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,22 @@ By default the `MomentDateAdapter` will creates dates in your time zone specific
|
||||
@NgModule({
|
||||
imports: [MatDatepickerModule, MatMomentDateModule],
|
||||
providers: [
|
||||
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
|
||||
{provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: {useUtc: true}}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
By default the `MomentDateAdapter` will parse dates in a
|
||||
[forgiving way](https://momentjs.com/guides/#/parsing/forgiving-mode/). This may result in dates
|
||||
being parsed incorrectly. You can change the default behaviour to
|
||||
[parse dates strictly](https://momentjs.com/guides/#/parsing/strict-mode/) by providing
|
||||
the `MAT_MOMENT_DATE_ADAPTER_OPTIONS` and setting it to `strict: true`.
|
||||
|
||||
```ts
|
||||
@NgModule({
|
||||
imports: [MatDatepickerModule, MatMomentDateModule],
|
||||
providers: [
|
||||
{provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: {strict: true}}
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user