Skip to content
Merged
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
11 changes: 11 additions & 0 deletions src/lib/datepicker/datepicker.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -246,6 +246,17 @@ export class MyComponent {

<!-- example(datepicker-moment) -->

By default the `MomentDateAdapter` will creates dates in your time zone specific locale. You can change the default behaviour to parse dates as UTC by providing the `MAT_MOMENT_DATA_ADAPTER_OPTIONS` and setting it to `useUtc: true`.

```ts
@NgModule({
imports: [MatDatepickerModule, MatMomentDateModule],
providers: [
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
]
})
```

It is also possible to create your own `DateAdapter` that works with any date format your app
requires. This is accomplished by subclassing `DateAdapter` and providing your subclass as the
`DateAdapter` implementation. You will also want to make sure that the `MAT_DATE_FORMATS` provided
Expand Down
11 changes: 9 additions & 2 deletions src/material-moment-adapter/adapter/index.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,7 +12,10 @@ import {
MAT_DATE_LOCALE,
MAT_DATE_FORMATS
} from '@angular/material';
import {MomentDateAdapter} from './moment-date-adapter';
import {
MomentDateAdapter,
MAT_MOMENT_DATE_ADAPTER_OPTIONS
} from './moment-date-adapter';
import {MAT_MOMENT_DATE_FORMATS} from './moment-date-formats';

export * from './moment-date-adapter';
Expand All@@ -21,7 +24,11 @@ export * from './moment-date-formats';

@NgModule({
providers: [
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]}
{
provide: DateAdapter,
useClass: MomentDateAdapter,
deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
}
],
})
export class MomentDateModule {}
Expand Down
30 changes: 28 additions & 2 deletions src/material-moment-adapter/adapter/moment-date-adapter.spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,7 +11,7 @@ import {async, inject, TestBed} from '@angular/core/testing';
import {DateAdapter, DEC, FEB, JAN, MAR, MAT_DATE_LOCALE} from '@angular/material/core';
import * as moment from 'moment';
import {MomentDateModule} from './index';
import {MomentDateAdapter} from './moment-date-adapter';
import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from './moment-date-adapter';


describe('MomentDateAdapter', () => {
Expand DownExpand Up@@ -143,7 +143,8 @@ describe('MomentDateAdapter', () => {
});

it('should create Moment date', () => {
expect(adapter.createDate(2017, JAN, 1).format()).toEqual(moment([2017, JAN, 1]).format());
expect(adapter.createDate(2017, JAN, 1).format())
.toEqual(moment([2017, JAN, 1]).format());
});

it('should not create Moment date with month over/under-flow', () => {
Expand All@@ -164,6 +165,10 @@ describe('MomentDateAdapter', () => {
expect(adapter.createDate(100, JAN, 1).year()).toBe(100);
});

it('should not create Moment date in utc format', () => {
expect(adapter.createDate(2017, JAN, 5).isUTC()).toEqual(false);
});

it("should get today's date", () => {
expect(adapter.sameDate(adapter.today(), moment()))
.toBe(true, "should be equal to today's date");
Expand DownExpand Up@@ -408,3 +413,24 @@ describe('MomentDateAdapter with LOCALE_ID override', () => {
expect(adapter.format(moment([2017, JAN, 2]), 'll')).toEqual('2 janv. 2017');
});
});

describe('MomentDateAdapter with MAT_MOMENT_DATE_ADAPTER_OPTIONS override', () => {
let adapter: MomentDateAdapter;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MomentDateModule],
providers: [
{ provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
]
}).compileComponents();
}));

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

it('should create Moment date in utc format if option useUtc is set', () => {
expect(adapter.createDate(2017, JAN, 5).isUTC()).toBeTruthy();
});
});
39 changes: 36 additions & 3 deletions src/material-moment-adapter/adapter/moment-date-adapter.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Inject, Injectable, Optional} from '@angular/core';
import {Inject, Injectable, Optional, InjectionToken} from '@angular/core';
import {DateAdapter, MAT_DATE_LOCALE} from '@angular/material';
// Depending on whether rollup is used, moment needs to be imported differently.
// Since Moment.js doesn't have a default export, we normally need to import using the `* as`
Expand All@@ -19,6 +19,31 @@ import {default as _rollupMoment, Moment} from 'moment';

const moment = _rollupMoment || _moment;

/** Configurable options for {@see MomentDateAdapter}. */
export interface MatMomentDateAdapterOptions {
/**
* 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;
}

/** InjectionToken for moment date adapter to configure options. */
export const MAT_MOMENT_DATE_ADAPTER_OPTIONS = new InjectionToken<MatMomentDateAdapterOptions>(
'MAT_MOMENT_DATE_ADAPTER_OPTIONS', {
providedIn: 'root',
factory: MAT_MOMENT_DATE_ADAPTER_OPTIONS_FACTORY
});


/** @docs-private */
export function MAT_MOMENT_DATE_ADAPTER_OPTIONS_FACTORY(): MatMomentDateAdapterOptions {
return {
useUtc: false
};
}


/** Creates an array and fills it with values. */
function range<T>(length: number, valueFunction: (index: number) => T): T[] {
Expand DownExpand Up@@ -48,7 +73,10 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
narrowDaysOfWeek: string[]
};

constructor(@Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string) {
constructor(@Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string,
@Optional() @Inject(MAT_MOMENT_DATE_ADAPTER_OPTIONS)
private options?: MatMomentDateAdapterOptions) {

super();
this.setLocale(dateLocale || moment.locale());
}
Expand DownExpand Up@@ -130,7 +158,12 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
}

let result = moment({year, month, date}).locale(this.locale);
let result;
if (this.options && this.options.useUtc) {
result = moment.utc({ year, month, date }).locale(this.locale);
} else {
result = moment({ year, month, date }).locale(this.locale);
}

// If the result isn't valid, the date must have been out of bounds for this month.
if (!result.isValid()) {
Expand Down