user3328775
user3328775

Reputation: 121

How can I set up a specific timezone for angular material datepicker?

I am developing an application in Angular 7. There is a date field where I use angular material datepicker inout. The problem is, datepicker always takes user local timezone when a date is selected. But I want to set it up to a specific timezone such as Eastern or Pacific timezone. When user will select a date, it should always come to that specific timezone ex. 06/22/2019 23:59 Pacific. I am new to angular. How can do it in Angular 7 application? Thank you in advance.

Upvotes: 9

Views: 20549

Answers (2)

alphapilgrim
alphapilgrim

Reputation: 3975

You'll need to the following:

  1. Create a user date format pipe.
  2. Create a custom date adapter that extends NativeDateAdapter.
  3. Import CustomDateAdapter into a module where it'll be used as useClass: CustomDateAdapter

app.module.ts

@NgModule({
  imports: [],
  declarations: [],
  exports: [],
  entryComponents: [],
  providers: [{
    provide: DateAdapter,
    useClass: CustomDateAdapter
  }]
})
export class AppModule {}

custom-date-adaptor.ts

export class CustomDateAdapter extends NativeDateAdapter {
  format(date: Date): string {
    const pipe = new UserDateFormatPipe();
    return pipe.transform(date);
  }
}

user-date-format.ts

// using moment.js
export class UserDateFormatPipe implements PipeTransform {

  transform(date: string | Date, timeFormat: string = ''): string {
    const defaultValues = {
      dateFormat: 'MM-dd-yyyy',
      language: 'en-US',
      timeZone: 'Central' //change defaults accordingly
    };
    const timeZoneOffset = moment(new Date(date))
      .tz(defaultValues)
      .format('Z');
    const datePipe = new DatePipe(defaultValues.language);
    const dateFormat = timeFormat ? `${defaultValues.dateFormat}  ${timeFormat}` : defaultValues.dateFormat;
    return datePipe.transform(date, dateFormat, timeZoneOffset, defaultValues.language);
  }
}

Stackblitz-Demo

Upvotes: 2

user10747134
user10747134

Reputation:

From the Angular Material docs, the default for the provided DateAdapter is to use the user's time zone.

You'll have to provide your own DateAdapter to override this.

I found this StackBlitz example that shows a possible way to solve this, but have not tried it.

Here is a snippet from there:

@Injectable()
export class CustomDateAdapter extends MomentDateAdapter {

  constructor( @Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string) {
    super(dateLocale);
  }

  parse(value, parseFormat) {
    if (value && typeof value == 'string') {
      console.log(moment(value, parseFormat, this.locale, true));
      return moment(value, parseFormat, this.locale, true);
    }
    return value ? moment(value).locale(this.locale) : undefined;
  }
}

And providing it (simple version):

{ provide: DateAdapter, useClass: CustomDateAdapter }

Upvotes: 3

Related Questions