день неверный в угловой материал 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 6

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 } } 
    ] 
})