在 GitHub 上与此相关的问题:
https://github.com/angular/material2/issues/7167
非常感谢您的帮助,我认为很多开发者需要一个解决方案。
在 GitHub 上与此相关的问题:
https://github.com/angular/material2/issues/7167
非常感谢您的帮助,我认为很多开发者需要一个解决方案。
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;
}
}
然后在AppModule组件中,你需要做如下操作:
providers: [
...
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
{ provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
{ provide: DateAdapter, useClass: MomentUtcDateAdapter },
...
],
只需在MatMomentDateAdapter
中使用选项useUtc: true
:
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 { }
MomentDateAdapter
作为DateAdapter
提供,则还需要在那里注入该选项对象:
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS] }
- Tomek 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 } }
]
})
{ provide: MAT_DATE_LOCALE, useValue: 'en-GB' }
时,这仍然可以节省一小时。 - jenson-button-event 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);
}
@Bruno_Cerecetto的代码工作得很好,但有一个小问题。当用户在文本框中输入日期而不是使用日期选择器选择日期时,他的代码不能正常工作,它会再次减少一天。为了使上述代码正常工作,你需要覆盖解析方法。每当用户在文本框中输入时,解析方法都会被调用。以下是对我有效的代码。我认为它可能会帮助某些人。
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;
}
我知道这是一个比较老的问题,但是由于我没有找到一个简单的答案,所以我会提供我成功的解决方法:
[ { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS,
useValue: { useUtc: true } },
{ provide: DateAdapter, useClass: MomentDateAdapter,
deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS] } ]
您还需要在dateAdapter
的deps
中指定适配器选项。这就是让我成功的原因。
var d = new Date('yourDate');
d.setMinutes( d.getMinutes() + d.getTimezoneOffset() );
d
现在应该是正确的日期。
以上所有解决方案都很好,但没有一个是一行代码的解决方法。如果您只想获取所选本地日期并将该数据作为日期对象发送到后端,请尝试以下方法:
框架:Angular,使用FormGroup和Formcontrol
let newDate = new Date(moment(this.date.value).format('YYYY-MM-DD'))
这不会将您的本地日期修改为字符串,它将保持为Date对象,并允许您以一致的方式使用数据类型,而且这是一个简单的修复。
选项1:
我遇到了同样的问题,并在后端(Java)中解决了它。你能在你的后端代码中解决吗?
以下是Java代码,如果有人需要相同的帮助,概念对于其他服务器端技术也应该是类似的。
模拟了相同的错误,以下是分析。
通过JSON打印 | “startdate”:“2018-02-08T18:30:00.000Z”。
提交之前打印 >>Fri Feb 09 2018 00:00:00 GMT+0530 (IST)
public static String dateConversion(String dt) {
Instant timestamp = Instant.parse(dt);
ZonedDateTime isttime = timestamp.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(isttime);
System.out.println(DateTimeFormatter.ofPattern("dd-MM-yyyy").format(isttime));
return DateTimeFormatter.ofPattern("dd-MM-yyyy").format(isttime);
}
选项2:(前端解决方案)
我没有尝试过这个选项,但是文档似乎非常清晰。
https://maggiepint.com/2016/05/14/moment-js-shows-the-wrong-date/
看一下。
目前,Angular Material日期选择器不支持不同的时区,并且它会给出一个UTC时间偏移量。但对我来说这不是问题,因为我将输出字符串保存到数据库中,当我将其返回给用户时,浏览器会显示正确的日期时间对象。 在控制台尝试此操作(我在+01区),您将看到所选日期:
new Date('2018-02-08T23:00:00.000Z')
Fri Feb 09 2018 00:00:00 GMT+0100 (CET)
MomentDateAdapter
,它在较旧版本的angular material中不受支持。你应该使用更新的版本(推荐)或从这里安装它。 - pouyada