角度材料datepicker中的日期不正确

Mot*_*msi 16 datepicker angular-material2 angular

当我选择日期时,我在字段中看到了正确的日期,但是,当我保存时,日期选择器发送我选择的日期前一天(3小时偏移)我使用角度响应形式和MatMomentDateModule用于日期选择器.

问题与时区有关,但我只想保存用户输入数据库的相同日期.

代码在这里重新编写:https://stackblitz.com/edit/angular-material-moment-adapter-example-kdk9nk file = app%2Fapp.module.ts

stackblitz上的问题

与githup相关的问题:

https://github.com/angular/material2/issues/7167

任何帮助表示赞赏,我认为很多开发人员需要一个解决方案.

小智 24

两天前,在https://github.com/angular/material2/issues/7167,Silthus发布了他的解决方法,覆盖了MomentJsD​​ataAdapter.我尝试过它,它可以作为全球任何地方的魅力.

首先,他添加了MomentUtcDateAdapter,扩展了MomentDateAdapter

import { Inject, Injectable, Optional } from '@angular/core';
import { MAT_DATE_LOCALE } from '@angular/material';   
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import { Moment } from 'moment';
import * as moment from 'moment';

@Injectable()
export class MomentUtcDateAdapter extends MomentDateAdapter {

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

  createDate(year: number, month: number, date: number): Moment {
    // Moment.js will create an invalid date if any of the components are out of bounds, but we
    // explicitly check each case so we can throw more descriptive errors.
    if (month < 0 || month > 11) {
      throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
    }

    if (date < 1) {
      throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
    }

    let result = moment.utc({ year, month, date }).locale(this.locale);

    // If the result isn't valid, the date must have been out of bounds for this month.
    if (!result.isValid()) {
      throw Error(`Invalid date "${date}" for month with index "${month}".`);
    }

    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在AppModule组件中,您必须这样做:

providers: [
    ...
    { provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
    { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
    { provide: DateAdapter, useClass: MomentUtcDateAdapter },
    ...
],
Run Code Online (Sandbox Code Playgroud)

  • 当用户在文本框中手动键入日期时,此方法不起作用。它没有触发该功能。 (4认同)
  • 这是解决方案的堆栈闪电战 https://stackblitz.com/edit/angular-material-moment-adapter-example-kdk9nk?file=app%2Fapp.module.ts (3认同)

Int*_*per 13

只需使用选项useUtc: trueMatMomentDateAdapter

import { MatMomentDateModule, MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter';

@NgModule({
  exports: [
    MatMomentDateModule,
    // ...
  ],
  providers: [
    { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
  ],
})
export class CustomModule { }
Run Code Online (Sandbox Code Playgroud)

  • 好的。有效。但 MatMoment 数据模块必须单独安装,因为它不是材质模块的一部分。以下内容应该有所帮助。npm install @angular/material-moment-adapter 参考:https://material.angular.io/components/datepicker/overview (2认同)
  • Moment 不再处于积极开发状态。不是理想的持续解决方案。 (2认同)

小智 8

也许这对某人有帮助。这是我从组件日期擦除 TimeZone OffSet 的示例方法

  addPriceListPeriod(priceListId: number, periodDateFrom: Date) {

    let UTCDate = Date.UTC(periodDateFrom.getFullYear(), periodDateFrom.getMonth(), periodDateFrom.getDate()) - periodDateFrom.getTimezoneOffset();

    periodDateFrom = new Date(UTCDate);

    const tempObject = {
      priceListId,
      fromDate: periodDateFrom
    }
    return this.httpClient.post('PriceLists/addPriceListPeriod', tempObject);
  }
Run Code Online (Sandbox Code Playgroud)


Küz*_*áté 5

https://github.com/angular/material2/issues/7167#issuecomment-402061126

您可以通过提供 MAT_MOMENT_DATA_ADAPTER_OPTIONS 并将其设置为 useUtc: true 来更改默认行为以将日期解析为 UTC。

@NgModule({ 
    imports: [MatDatepickerModule, MatMomentDateModule], 
    providers: [ 
        { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } } 
    ] 
})
Run Code Online (Sandbox Code Playgroud)


小智 5

@Bruno_Cerecetto 的代码工作正常,但有一个小问题。当用户在文本框中键入日期而不是使用日期选择器选择日期时,他的代码将不起作用,它会再次减少一天。要正确使用上面的代码,您还需要重写 parse 方法。每次用户在文本框中键入内容时都会调用 Parse 方法。这是适合我的代码。我认为这可能对某人有帮助。

parse(value: any, parseFormat: string | string[]): Moment | null {
    console.log(value)
    if (value && typeof value === 'string') {
      return moment.utc(value, parseFormat, this.locale, true);
    }
    return value ? moment.utc(value).locale(this.locale) : null;
  }
Run Code Online (Sandbox Code Playgroud)