I'm using the angular-material-components/datetime-picker as described here in their doc/demo site - https://h2qutc.github.io/angular-material-components/#/datetimepicker.
How can I get the time zone (non-UTC) in the picked date time value? Preferred value have the format: Feb 10, 2024, 06:00 PM CST.
If I go the NgxMatNativeDateModule I specify the following format ->
const INTL_DATE_INPUT_FORMAT = {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short'
};
const MAT_DATE_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: INTL_DATE_INPUT_FORMAT,
},
display: {
dateInput: INTL_DATE_INPUT_FORMAT,
monthYearLabel: { year: 'numeric', month: 'short' },
dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
monthYearA11yLabel: { year: 'numeric', month: 'long' },
},
This produces the following in the date picker input but it's in UTC rather than the local time zone which is what I'm looking for. I'm not sure how to get around that.
Otherwise I can use the NgxMatMomentModule and specify a date format like
export const MOMENT_DATETIME_WITH_SECONDS_FORMAT = 'MM/d/y, h:mm A ZZ';
const CUSTOM_MOMENT_FORMATS: NgxMatDateFormats = {
parse: {
dateInput: MOMENT_DATETIME_WITH_SECONDS_FORMAT,
},
display: {
dateInput: MOMENT_DATETIME_WITH_SECONDS_FORMAT,
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};
That produces the following and displays the time zone as an hour offset but I prefer the string like 'CST'. Is there a way to do that? Do I need to make a custom adapter to do that potentially?
Here is a copy of my custom Date adapter:
import { DatePipe } from '@angular/common';
import { NativeDateAdapter } from '@angular/material/core';
const USE_TIMEZONE = 'UTC';
function range<T>(length: number, valueFunction: (index: number) => T): T[] {
return Array.from({ length }, (_, i) => valueFunction(i));
}
function createDtf(locale: string, options: Intl.DateTimeFormatOptions) {
return new Intl.DateTimeFormat(locale, {
...options,
timeZone: USE_TIMEZONE,
});
}
export class AppDateAdapter extends NativeDateAdapter {
private formatDate(dtf: Intl.DateTimeFormat, date: Date): string {
const d = new Date(
Date.UTC(
date.getFullYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
)
);
return dtf.format(d);
}
override getFirstDayOfWeek(): number {
return 1;
}
override getDayOfWeekNames(style: 'long' | 'short' | 'narrow'): string[] {
const dtf = createDtf(this.locale, { weekday: 'short' });
return range(7, (i) => this.formatDate(dtf, new Date(2017, 0, i + 1)));
}
override getDateNames(): string[] {
const dtf = createDtf(this.locale, { day: '2-digit' });
return range(31, (i) => this.formatDate(dtf, new Date(2017, 0, i + 1)));
}
override format(date: any, displayFormat: any): any {
return new DatePipe(this.locale).transform(date, displayFormat);
}
}
import { DEFAULT_CURRENCY_CODE, LOCALE_ID, Provider } from '@angular/core';
import {
DateAdapter,
MAT_DATE_FORMATS,
MAT_DATE_LOCALE,
} from '@angular/material/core';
// German
import localeDe from '@angular/common/locales/de';
import localeDeExtra from '@angular/common/locales/extra/de';
import { registerLocaleData } from '@angular/common';
registerLocaleData(localeDe, localeDeExtra);
import { AppDateAdapter } from './locale.adapter';
export function provideLocaleConfig(): Provider[] {
return [
{
provide: LOCALE_ID,
useValue: 'de-DE',
},
{
provide: MAT_DATE_FORMATS,
useValue: {
parse: { dateInput: 'mediumDate' },
display: {
dateInput: 'mediumDate',
monthLabel: 'MMMM',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
},
},
{
provide: DEFAULT_CURRENCY_CODE,
useValue: '€',
},
{
provide: DateAdapter,
useClass: AppDateAdapter ,
deps: [MAT_DATE_LOCALE],
},
];
}
// app.config.ts in angular v17+
export const appConfig: ApplicationConfig = {
providers: [
//...
provideLocaleConfig()
//...
],
};
For older version you can just provide it in same way in app.module:
providers: [
//...
provideLocaleConfig()
//...
],