Material Datepicker选中日期与发送日期差一天问题咨询
Angular Material Datepicker 选中日期与实际发送日期差一天问题
代码实现
HTML模板:
<mat-form-field class="w-full"> <mat-label>{{ "DATE" | translate }}</mat-label> <input matInput [matDatepicker]="datePicker" [formControlName]="'date'" /> <mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle> <mat-datepicker #datePicker></mat-datepicker> <mat-error> {{ 'REQUIRED' | translate }} </mat-error> </mat-form-field>
组件配置:
const MY_DATE_FORMAT = { parse: { dateInput: 'DD/MM/YYYY', }, display: { dateInput: 'DD/MM/YYYY', monthYearLabel: 'MMMM YYYY', dateA11yLabel: 'LL', monthYearA11yLabel: 'MMMM YYYY' } }; @Component({ selector: 'app-document', templateUrl: './document.component.html', styleUrls: ['./document.component.scss'], encapsulation: ViewEncapsulation.None, providers: [ { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] }, { provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMAT }, ], })
问题现象
选择日期后,实际发送的日期比选中日期早一天。例如选中10/05/2024时,保存前console.log显示为"2024-05-09T22:00:00.000Z",日期变为09而非10。
原因分析
这完全是时区差异导致的:
- 你使用的
MomentDateAdapter默认会把选中的本地日期转换成UTC时间存储。比如你的本地时区是UTC+2(如欧洲中部时间),选中本地的2024-05-10时,转换为UTC时间就是前一天的22点——也就是2024-05-09T22:00:00.000Z。 - 直接打印日期对象时,输出的是UTC时间戳,看起来像日期少了一天,但这只是时区转换后的正常结果。
解决办法
方法1:转换为本地日期的UTC零点
在发送请求前,将日期处理为本地时区零点对应的UTC时间,确保日期值正确:
// 假设formControl的value是moment对象 const selectedDate = this.form.get('date').value; const dateToSend = selectedDate.startOf('day').utc().format();
方法2:直接拼接本地日期的ISO格式
忽略时区,直接提取本地日期的年、月、日,拼接成标准ISO格式的零点时间:
const date = this.form.get('date').value; const isoDate = `${date.year()}-${String(date.month() + 1).padStart(2, '0')}-${String(date.date()).padStart(2, '0')}T00:00:00.000Z`;
方法3:配置适配器使用本地时区
修改DateAdapter的配置,让它始终以本地时区存储日期(注意:跨时区场景下可能有问题,需结合业务选择):
// 调整组件providers中的DateAdapter配置 { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE], useFactory: (locale: string) => { const adapter = new MomentDateAdapter(locale); adapter.setLocale(locale); moment.locale(locale); // 强制使用本地时区 moment.tz.setDefault(moment.tz.guess()); return adapter; } }
内容的提问来源于stack exchange,提问作者flaw
相关产品推荐
相关产品推荐

