день неверный в угловой материал datepicker
Когда я выбираю дату, я вижу правильную дату в поле, но, когда я сохраняю, datepicker отправляет за день до выбранной даты ( смещение на 3 часа ) я использую угловую реактивную форму и MatMomentDateModule для выбора даты .
Проблема связана с часовыми поясами, но я просто хочу сохранить ту же дату, которую пользователь вводит в базу данных .
Код, представленный здесь : https://stackblitz.com/edit/angular-material-moment-adapter-example-kdk9nk?file=app%2Fapp.module.ts
Проблема, связанная с этим на githup:
Https://github.com/angular/material2/issues/7167
Любая помощь ценится, и я думаю, что многие разработчики нуждаются в решении для этого .
5 ответов:
Два дня назад, в https://github.com/angular/material2/issues/7167 , Силтус опубликовал свой обходной путь, который переопределяет MomentJsDataAdapter. Я попробовал его, и он сработал как заклинание из любой точки земного шара.
Сначала он добавил 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; } }
А затем в компоненте AppModule вы должны сделать следующее:
providers: [ ... { provide: MAT_DATE_LOCALE, useValue: 'en-GB' }, { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS }, { provide: DateAdapter, useClass: MomentUtcDateAdapter }, ... ],
Вариант 1: Имел ту же проблему и решил ее в backed (Java) можете ли вы решить это в вашем бэкэнд-коде.
Представление кода java на случай, если кому-то понадобится такая же помощь. концепция должна быть аналогичной и для других серверных технологий.Смоделирована та же ошибка и ниже приведен анализ.
Печать через JSON | "startdate": "2018-02-08T18: 30: 00.000 Z".
Печать перед отправкой > > Пт февраль 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 date picker не поддерживает различные часовые пояса в данный момент, и это дает вам смещение времени UTC. Но для меня это не проблема, так как я сохраняю выходную строку в свою базу данных, и когда я возвращаю ее обратно пользователю, браузер показывает правильный объект даты и времени. Попробуйте сделать это в консоли (im в зоне +01) , и вы увидите выбранную дату:
new Date('2018-02-08T23:00:00.000Z') Fri Feb 09 2018 00:00:00 GMT+0100 (CET)
Другим решением является изменение объекта даты перед сохранением в базу данных, что не является лучшим решением. практика.
Наконец, если вы используете момент.js в вашем приложении вы можете попробовать
MomentDateAdapter
и посмотреть, поможет ли это вам. Просто добавьтеMatMomentDateModule
в ваше приложение, как описано здесь.
Спасибо @ankit-raonka ответ здесь : https://stackoverflow.com/a/48761312/6423656
Используя ControlValueAccessor решил мою проблему и вот рабочий пример : https://stackblitz.com/edit/angular-dlxnmx?file=app%2Fcva-date.component.ts
Спасибо всем за ответы , я думаю, что эта проблема также может быть решена с помощью метода синтаксического анализа адаптера даты момента, но мне нравится ControlValueAccessor try, поскольку я контролирую все входные аспекты + уменьшить код написано, когда я хочу использовать его в моем html .
Https://github.com/angular/material2/issues/7167#issuecomment-402061126
Вы можете изменить поведение по умолчанию, чтобы анализировать даты как UTC по предоставление функции MAT_MOMENT_DATA_ADAPTER_OPTIONS и установка ее в useUtc: верно.
@NgModule({ imports: [MatDatepickerModule, MatMomentDateModule], providers: [ { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } } ] })