Search code examples
angularmoment-timezonemat-datepicker

Problem with Timezone converter in angular


I have a problem with time zone in my angular application in my components I use a pre-share component named (datepicker), I use matDatepicker:

<mat-form-field [appearance]="appearance" class="pax-datepicker">
  <mat-label *ngIf="fieldLabel">{{ fieldLabel }} </mat-label>
  <input
    matInput
    [matDatepicker]="picker"
    [name]="name"
    [ngModel]="ngModel"
    (ngModelChange)="onChangeDate($event)"
    [min]="minDate"
    [max]="maxDate"
    [required]="required"
    [readonly]="true"
    [ngClass]="{ changable: !readonly }"
  />
  <mat-datepicker-toggle
    matSuffix
    [for]="picker"
    [disabled]="readonly"
  ></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

and

ngOnChanges(changes: SimpleChanges): void {
    if (changes['ngModel'] && changes['ngModel'].currentValue) {
      this.ngModel = moment(this.ngModel?.replace(' ', '')).format(
        'YYYY-MM-DD'
      );
    }
  }

onChangeDate(e: any) {
    this.dateChange.emit(moment(e).format('YYYY-MM-DDTHH:mm:ss.SSSZ'));
    this.ngModelChange.emit(e);
    this.blur.emit(e);
  }

and this is an example where I use this component:

    <pax-datepicker
      class="col-lg-4"
      #DueDate
      [fieldLabel]="locale.getText('due-date')"
      name="DueDate"
      [minDate]="dueDateMinDate"
      [(ngModel)]="model.DueDate"
    ></pax-datepicker>

as you see I'm using moment() and format() to convert the data for example (Tue Sep 26 2023 00:00:00 GMT-0400 (Eastern Daylight Time) 2023-09-26T00:00:00.000-04:00) to (9/26/2023) as today

but when I reload my page it shows me a day before (9/25/2023) as I checked, I save correct data and get the correct data from server but some how it shows me wrong time as I also checked in some time zone it works just fine but in some other time zone like Canada etc. it shows wrong time. I want to fix it for all time zone not just specific time zone.

I tried

ngOnChanges(changes: SimpleChanges): void {
    if (changes['ngModel'] && changes['ngModel'].currentValue) {
      // Assuming that 'ngModel' contains a UTC date string
      const utcDate = new Date(changes['ngModel'].currentValue);

      // Format the date as 'YYYY-MM-DD' in the user's local time zone
      this.ngModel = utcDate.toLocaleDateString('en-US', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
      });
    }
  }

I also tried to use date() to separate Year and Month and Day to pass it to my component in order to show it but every change caused not to showing anything

so it didn't work as I expected


Solution

  • One way to solve that problem is:

    ngOnChanges(changes: SimpleChanges): void {
     if (changes['ngModel'] && changes['ngModel'].currentValue) {
      this.ngModel=String(this.ngModel).split(' ')[0];
     }  
    }
    

    this way you convert YYYY-MM-DDTHH:mm:ss.SSSZ to YYYY-MM-DD and just like that you could transfer it to your (mat-datepicker) HTML