Дата один день назад - PullRequest
       10

Дата один день назад

0 голосов
/ 10 января 2020

Я выбираю дату 01 мая 1985 в моем датчике и отправляю dateOfBirth.value на мой сервер, чтобы он мог быть сохранен в базе данных.

<mat-form-field>
  <label><input #dateOfBirth matInput (blur)="_update('personal', 'dateOfBirth', dateOfBirth.value)" (click)="picker.open()" [matDatepicker]="picker" placeholder="Choose a date" formControlName="dateOfBirth" autocomplete="off" [max]="maxDate" [min]="minDate"></label>
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker touchUi #picker startView="multi-year"></mat-datepicker>
  <mat-error *ngIf="profileFormGroup.get('dateOfBirth').errors">Date is not valid</mat-error>
</mat-form-field>

Всякий раз, когда я повторяю sh страница, выбранная дата все еще должна быть видна.

Моя проблема в том, что я выбрал дату 05/01/1985 , но мой указатель даты показывает мне 4/30/1985 . Почему?

private static _formatDate(timestamp: number): string {
  console.log(timestamp); // Returns 483746400000
  const date = new Date(+timestamp);
  console.log(date.getDay()); // Returns 3 but it should be 1
  return date.toISOString().substring(0, 10);
}

ngOnInit() {
  this.profileService.getEntities().subscribe(data => {
  this.profileFormGroup.get('dateOfBirth').patchValue(ProfileComponent._formatDate(data.dateOfBirth));
  });
}

Это способ хранения метки времени в моей базе данных:

private _update(tableName: string, columnName: string, theValue: any) {
  // Set the correct value of dateOfBirth
  console.log(theValue); // Returns 5/1/1985
  if (columnName === 'dateOfBirth') {
    const splitDate = theValue.split('/');
    const newDate = `${splitDate[2]}/${splitDate[0]}/${splitDate[1]}`;
    theValue = new Date(newDate).getTime();
    console.log(theValue); // Returns 483746400000
  }

  const json = {
      table: tableName,
      column: columnName,
      value: theValue
  };

  this.profileService.update(json).subscribe(result => {
    console.log(result);
  });
}

Я также проверил другие примеры, такие как этот на Stackblitz, Если вы выберете дату 01/05/2020 , на выходе будет 2020-04-30T22: 00: 00.000Z , что неверно.

1 Ответ

1 голос
/ 10 января 2020

В зависимости от вашего региона, май месяц попадает в летнее время.

Установка даты 05.01.1985 должна выглядеть как 1985-05-01T00:00.000+1:00, если вы сохраните часовой пояс.

Похоже, происходит то, что вы извлекаете дату в UT C. Это преобразует дату в +0: 00 и, таким образом, перенесет вас в предыдущий день по номеру 1985-04-30T23:00.000+0.00.

. Если вы попытаетесь использовать Stackblitz, проблема доказана - выберите дату до конца марта и после конец октября - эти даты работают нормально, поскольку они не при переходе на летнее время.

Ваша функция форматирования даты извлекает дату, используя .toISOString(). Согласно Моцциле (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString), это всегда вернет время UT C, и вы получите дату на час позже, а поскольку это в полночь, она падает на предыдущий день.

Поскольку вас интересует только дата, а средство выбора даты может смещаться до 12 часов каждый раз, когда мы можем проверить это.

Дата по умолчанию всегда полночь, поэтому все, что раньше UT C, подойдет, так как останется той же датой. Все, что за UT C, go вернется на 12 часов и на следующий день.

В коде проверка смещения часового пояса скажет нам, если мы отстаем. Если это так, то мы хотим добавить часы к объекту datetime, чтобы при использовании toISOString мы все равно выбирали дату.

, поэтому функция должна выглядеть следующим образом:

const date = new Date(+timestamp);
const offset = date.getTimezoneOffset();
if (offset < 0) {
    date.setHours(12,0,0);
}
return date.toISOString().substring(0,10);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...