Created
December 22, 2017 01:52
-
-
Save maburdi94/9500d90febb3caa519c3f2f8e996f9dc to your computer and use it in GitHub Desktop.
Angular Date Adapter for Luxon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Inject, Injectable, InjectionToken, LOCALE_ID, Optional} from '@angular/core'; | |
import {DateAdapter} from '@angular/material'; | |
import {DateTime} from 'luxon/build/node/luxon'; | |
declare var DateTime: { | |
year: number; | |
month: number; | |
day: number; | |
weekday: number; | |
daysInMonth: number; | |
isValid: boolean; | |
fromJSDate(value: Date, opts?: any); | |
fromObject(value: Object); | |
fromMillis(value: number, opts?: any); | |
fromString(value: string, parseFormat: string, opts?: any); | |
fromISO(value: string); | |
invalid(); | |
local(...args: any[]); | |
plus(value: any); | |
toFormat(format: string); | |
toISO(); | |
}; | |
export const DATE_LOCALE = new InjectionToken<string>('DATE_LOCALE'); | |
/** Provider for MAT_DATE_LOCALE injection token. */ | |
export const DATE_LOCALE_PROVIDER = {provide: DATE_LOCALE, useExisting: LOCALE_ID}; | |
const ISO_8601_REGEX = | |
/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/; | |
/** Creates an array and fills it with values. */ | |
function range<T>(length: number, valueFunction: (index: number) => T): T[] { | |
const valuesArray = Array(length); | |
for (let i = 0; i < length; i++) { | |
valuesArray[i] = valueFunction(i); | |
} | |
return valuesArray; | |
} | |
@Injectable() | |
export class LuxonDateAdapter extends DateAdapter<DateTime> { | |
constructor(@Optional() @Inject(DATE_LOCALE) dateLocale: string) { | |
super(); | |
this.setLocale(dateLocale || DateTime.local().locale); | |
} | |
getYear(date: DateTime): number { | |
return date.year; | |
} | |
getMonth(date: DateTime): number { | |
return date.month; | |
} | |
getDate(date: DateTime): number { | |
return date.day; | |
} | |
getDayOfWeek(date: DateTime): number { | |
return date.weekday; | |
} | |
getMonthNames(style): string[] { | |
return Info.months(style, {locale: this.locale}); | |
} | |
getDateNames(): string[] { | |
return range(31, (i) => DateTime.local(2018, 1, i, {locale: this.locale}).toFormat('d')); | |
} | |
getDayOfWeekNames(style): string[] { | |
return Info.weekdays(style, {locale: this.locale}); | |
} | |
getYearName(date: DateTime): string { | |
return date.toFormat('y'); | |
} | |
getFirstDayOfWeek(): number { | |
return 0; | |
} | |
getNumDaysInMonth(date: DateTime): number { | |
return date.daysInMonth; | |
} | |
clone(date: DateTime): DateTime { | |
return date; | |
} | |
createDate(year: number, month: number, date: number): DateTime { | |
return DateTime.local(year, month + 1, date, {locale: this.locale}); | |
} | |
today(): DateTime { | |
return DateTime.local({locale: this.locale}); | |
} | |
parse(value: any, parseFormat: any): DateTime | null { | |
if (!value) return null; | |
if (typeof value == 'string') | |
return DateTime.fromString(value, parseFormat, {locale: this.locale}); | |
else if (typeof value == 'number') | |
return DateTime.fromMillis(value, {locale: this.locale}); | |
else if (value instanceof Date) | |
return DateTime.fromJSDate(value, {locale: this.locale}); | |
else if (typeof value == 'object') | |
return DateTime.fromObject({...value, locale: this.locale}); | |
else return null; | |
} | |
format(date: DateTime, displayFormat: string): string { | |
return date.toFormat(displayFormat); | |
} | |
addCalendarYears(date: DateTime, years: number): DateTime { | |
return date.plus({years}); | |
} | |
addCalendarMonths(date: DateTime, months: number): DateTime { | |
return date.plus({months}); | |
} | |
addCalendarDays(date: DateTime, days: number): DateTime { | |
return date.plus({days}); | |
} | |
toIso8601(date: DateTime): string { | |
return date.toISO(); | |
} | |
isDateInstance(obj: any): boolean { | |
return obj instanceof DateTime; | |
} | |
isValid(date: DateTime): boolean { | |
return date.isValid; | |
} | |
invalid(): DateTime { | |
return DateTime.invalid(); | |
} | |
deserialize(value: any): DateTime | null { | |
if (typeof value === 'string') { | |
if (!value) { | |
return null; | |
} | |
if (ISO_8601_REGEX.test(value)) { | |
const date = DateTime.local(value); | |
if (this.isValid(date)) { | |
return date; | |
} | |
} | |
} | |
return super.deserialize(value); | |
} | |
setLocale(locale: any): void { | |
super.setLocale(locale); | |
} | |
} |
Which version of material-luxon-adapter supports to Angular 13?
For others arriving here, Angular Material now supports Luxon.
NPM: @angular/material-luxon-adapter
import { LuxonDateAdapter, MAT_LUXON_DATE_ADAPTER_OPTIONS, MAT_LUXON_DATE_FORMATS } from '@angular/material-luxon-adapter'; import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; @Component({ selector: 'app-download-report-dialog', templateUrl: './download-report-dialog.component.html', styleUrls: ['./download-report-dialog.component.scss'], providers: [ { provide: DateAdapter, useClass: LuxonDateAdapter, deps: [MAT_DATE_LOCALE, MAT_LUXON_DATE_ADAPTER_OPTIONS] }, { provide: MAT_DATE_FORMATS, useValue: MAT_LUXON_DATE_FORMATS }, ] })
@daverickdunn Thank you, works fine
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For others arriving here, Angular Material now supports Luxon.
NPM: @angular/material-luxon-adapter