You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular mat-datepicker显示日期错误:时区问题

问题描述

数据库中以UTC格式存储的日期为:

this.eventItem.date: "2023-06-21T00:00:00.000Z"

但表单输入框显示的值为2023-06-20,日期天数错误,推测是时区问题。当前声称所在时区为+3,执行console.log(new Date(this.eventItem.date));后,日志输出:

'Tue Jun 20 2023 21:00:00 GMT-0300 (hora estándar de Argentina)'

相关代码如下:

TypeScript 初始化代码

initializeForm(): void {
  this.detailsEventForm = this.fb.group({
    isActive: [this.eventItem.isActive],
    date: '2023-06-21',
    shifts: [this.eventItem.shifts]
  });
}

HTML 表单代码

<mat-form-field floatLabel="auto" appearance="outline" color="primary">
  <mat-label>Date</mat-label>
  <input
    matInput
    formControlName="date"
    [matDatepicker]="datePickerDate"
    readonly
    (click)="datePickerDate.open()">
  <mat-datepicker-toggle [for]="datePickerDate" matSuffix></mat-datepicker-toggle>
  <mat-datepicker #datePickerDate></mat-datepicker>
</mat-form-field>

解决方法

这个问题是Angular Material Datepicker默认按本地时区解析UTC日期导致的偏移,结合你的日志(实际运行环境为阿根廷GMT-3时区),提供两种可靠解决方式:

方式一:全局配置UTC日期适配器

让Datepicker全程以UTC时区处理日期,避免时区偏移:

  1. 自定义UTC适配类
import { NativeDateAdapter } from '@angular/material/core';

export class UtcDateAdapter extends NativeDateAdapter {
  override parse(value: any): Date | null {
    if (typeof value === 'string' && value.includes('Z')) {
      return new Date(value);
    }
    return super.parse(value);
  }

  override format(date: Date, displayFormat: Object): string {
    const utcDate = new Date(date.getTime() + date.getTimezoneOffset() * 60000);
    return super.format(utcDate, displayFormat);
  }
}
  1. 在模块中注册适配器
import { NgModule } from '@angular/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatNativeDateModule } from '@angular/material/core';
import { UtcDateAdapter } from './utc-date-adapter';

@NgModule({
  imports: [MatDatepickerModule, MatNativeDateModule],
  providers: [
    { provide: NativeDateAdapter, useClass: UtcDateAdapter }
  ]
})
export class AppModule {}

方式二:手动转换UTC日期为本地正确格式

在初始化表单时,将UTC日期转换为运行环境时区的正确日期字符串:

initializeForm(): void {
  const utcDate = new Date(this.eventItem.date);
  // 针对阿根廷GMT-3时区,UTC转本地日期
  const localDate = new Date(utcDate.getTime() - 3 * 60 * 60 * 1000);
  const formattedDate = localDate.toISOString().split('T')[0];

  this.detailsEventForm = this.fb.group({
    isActive: [this.eventItem.isActive],
    date: formattedDate,
    shifts: [this.eventItem.shifts]
  });
}

如果后续确认运行环境确实是+3时区,将转换逻辑改为utcDate.getTime() + 3 * 60 * 60 * 1000即可


内容的提问来源于stack exchange,提问作者sonEtLumiere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 06:10:39