Skip to content

Commit 439d6fc

Browse files
authored
feat(material-luxon-adapter): add option to set default calendar (#27453)
* feat(material-luxon-adapter): add option to set default calendar Add defaultOutputCalendar option to be able to change default calndar through MAT_LUXON_DATE_ADAPTER_OPTIONS * feat(material-luxon-adapter): update options to add default calendar Update options of luxon-date-adapter to add defaultOutputCalendar to be able to change default calndar through MAT_LUXON_DATE_ADAPTER_OPTIONS
1 parent d098bd2 commit 439d6fc

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

src/material-luxon-adapter/adapter/luxon-date-adapter.spec.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {LOCALE_ID} from '@angular/core';
1010
import {TestBed, waitForAsync} from '@angular/core/testing';
1111
import {DateAdapter, MAT_DATE_LOCALE} from '@angular/material/core';
12-
import {DateTime, FixedOffsetZone, Settings} from 'luxon';
12+
import {CalendarSystem, DateTime, FixedOffsetZone, Settings} from 'luxon';
1313
import {LuxonDateModule} from './index';
1414
import {MAT_LUXON_DATE_ADAPTER_OPTIONS} from './luxon-date-adapter';
1515

@@ -632,6 +632,41 @@ describe('LuxonDateAdapter with MAT_LUXON_DATE_ADAPTER_OPTIONS override', () =>
632632
});
633633
});
634634

635+
describe('LuxonDateAdapter with MAT_LUXON_DATE_ADAPTER_OPTIONS override for defaultOutputCalendar option', () => {
636+
let adapter: DateAdapter<DateTime>;
637+
638+
const calendarExample: CalendarSystem = 'islamic';
639+
640+
beforeEach(waitForAsync(() => {
641+
TestBed.configureTestingModule({
642+
imports: [LuxonDateModule],
643+
providers: [
644+
{
645+
provide: MAT_LUXON_DATE_ADAPTER_OPTIONS,
646+
useValue: {defaultOutputCalendar: calendarExample},
647+
},
648+
],
649+
}).compileComponents();
650+
651+
adapter = TestBed.inject(DateAdapter);
652+
}));
653+
654+
describe(`use ${calendarExample} calendar`, () => {
655+
it(`should create Luxon date in ${calendarExample} calendar`, () => {
656+
// Use 0 since createDate takes 0-indexed months.
657+
expect(adapter.createDate(2017, 0, 2).toLocaleString()).toBe(
658+
DateTime.local(2017, JAN, 2, {outputCalendar: calendarExample}).toLocaleString(),
659+
);
660+
});
661+
662+
it(`should create today in ${calendarExample} calendar`, () => {
663+
expect(adapter.today().toLocaleString()).toBe(
664+
DateTime.local({outputCalendar: calendarExample}).toLocaleString(),
665+
);
666+
});
667+
});
668+
});
669+
635670
function assertValidDate(adapter: DateAdapter<DateTime>, d: DateTime | null, valid: boolean) {
636671
expect(adapter.isDateInstance(d))
637672
.not.withContext(`Expected ${d} to be a date instance`)

src/material-luxon-adapter/adapter/luxon-date-adapter.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
DateTime as LuxonDateTime,
1313
Info as LuxonInfo,
1414
DateTimeOptions as LuxonDateTimeOptions,
15+
CalendarSystem as LuxonCalendarSystem,
1516
} from 'luxon';
1617

1718
/** Configurable options for the `LuxonDateAdapter`. */
@@ -27,6 +28,12 @@ export interface MatLuxonDateAdapterOptions {
2728
* Changing this will change how Angular Material components like DatePicker shows start of week.
2829
*/
2930
firstDayOfWeek: number;
31+
32+
/**
33+
* Sets the output Calendar.
34+
* Changing this will change how Angular Material components like DatePicker output dates.
35+
*/
36+
defaultOutputCalendar: LuxonCalendarSystem;
3037
}
3138

3239
/** InjectionToken for LuxonDateAdapter to configure options. */
@@ -43,6 +50,7 @@ export function MAT_LUXON_DATE_ADAPTER_OPTIONS_FACTORY(): MatLuxonDateAdapterOpt
4350
return {
4451
useUtc: false,
4552
firstDayOfWeek: 0,
53+
defaultOutputCalendar: 'gregory',
4654
};
4755
}
4856

@@ -60,6 +68,7 @@ function range<T>(length: number, valueFunction: (index: number) => T): T[] {
6068
export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
6169
private _useUTC: boolean;
6270
private _firstDayOfWeek: number;
71+
private _defaultOutputCalendar: LuxonCalendarSystem;
6372

6473
constructor(
6574
@Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string,
@@ -70,6 +79,7 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
7079
super();
7180
this._useUTC = !!options?.useUtc;
7281
this._firstDayOfWeek = options?.firstDayOfWeek || 0;
82+
this._defaultOutputCalendar = options?.defaultOutputCalendar || 'gregory';
7383
this.setLocale(dateLocale || LuxonDateTime.local().locale);
7484
}
7585

@@ -91,7 +101,11 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
91101
}
92102

93103
getMonthNames(style: 'long' | 'short' | 'narrow'): string[] {
94-
return LuxonInfo.months(style, {locale: this.locale});
104+
// Adding outputCalendar option, because LuxonInfo doesn't get effected by LuxonSettings
105+
return LuxonInfo.months(style, {
106+
locale: this.locale,
107+
outputCalendar: this._defaultOutputCalendar,
108+
});
95109
}
96110

97111
getDateNames(): string[] {
@@ -113,7 +127,7 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
113127
}
114128

115129
getYearName(date: LuxonDateTime): string {
116-
return date.toFormat('yyyy');
130+
return date.toFormat('yyyy', this._getOptions());
117131
}
118132

119133
getFirstDayOfWeek(): number {
@@ -125,10 +139,12 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
125139
}
126140

127141
clone(date: LuxonDateTime): LuxonDateTime {
128-
return LuxonDateTime.fromObject(date.toObject());
142+
return LuxonDateTime.fromObject(date.toObject(), this._getOptions());
129143
}
130144

131145
createDate(year: number, month: number, date: number): LuxonDateTime {
146+
const options = this._getOptions();
147+
132148
if (month < 0 || month > 11) {
133149
throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
134150
}
@@ -139,18 +155,20 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
139155

140156
// Luxon uses 1-indexed months so we need to add one to the month.
141157
const result = this._useUTC
142-
? LuxonDateTime.utc(year, month + 1, date)
143-
: LuxonDateTime.local(year, month + 1, date);
158+
? LuxonDateTime.utc(year, month + 1, date, options)
159+
: LuxonDateTime.local(year, month + 1, date, options);
144160

145161
if (!this.isValid(result)) {
146162
throw Error(`Invalid date "${date}". Reason: "${result.invalidReason}".`);
147163
}
148164

149-
return result.setLocale(this.locale);
165+
return result;
150166
}
151167

152168
today(): LuxonDateTime {
153-
return (this._useUTC ? LuxonDateTime.utc() : LuxonDateTime.local()).setLocale(this.locale);
169+
const options = this._getOptions();
170+
171+
return this._useUTC ? LuxonDateTime.utc(options) : LuxonDateTime.local(options);
154172
}
155173

156174
parse(value: any, parseFormat: string | string[]): LuxonDateTime | null {
@@ -201,15 +219,15 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
201219
}
202220

203221
addCalendarYears(date: LuxonDateTime, years: number): LuxonDateTime {
204-
return date.plus({years}).setLocale(this.locale);
222+
return date.reconfigure(this._getOptions()).plus({years});
205223
}
206224

207225
addCalendarMonths(date: LuxonDateTime, months: number): LuxonDateTime {
208-
return date.plus({months}).setLocale(this.locale);
226+
return date.reconfigure(this._getOptions()).plus({months});
209227
}
210228

211229
addCalendarDays(date: LuxonDateTime, days: number): LuxonDateTime {
212-
return date.plus({days}).setLocale(this.locale);
230+
return date.reconfigure(this._getOptions()).plus({days});
213231
}
214232

215233
toIso8601(date: LuxonDateTime): string {
@@ -256,6 +274,7 @@ export class LuxonDateAdapter extends DateAdapter<LuxonDateTime> {
256274
return {
257275
zone: this._useUTC ? 'utc' : undefined,
258276
locale: this.locale,
277+
outputCalendar: this._defaultOutputCalendar,
259278
};
260279
}
261280
}

0 commit comments

Comments
 (0)