Website-Suche

typescript - Angular Material Datumswähler: UTC-Problem bei der Datumsanalyse 1 Tag vorher


Ich weiß, dass es mehrere Threads dazu gibt und ich habe sie alle gelesen, aber ich konnte das seit Tagen nicht beheben. Ich könnte eine Lösung gefunden haben, aber sie scheint mir zu dreckig zu sein.

Also habe ich wie andere Benutzer dasselbe Problem mit dem DatePicker. Für mich ist es der Angular Material Datepicker mat-datepicker

Wenn ich den Wert protokolliere, erhalte ich das richtige Ergebnis:

Wed Dec 24 1999 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

aber in der Anfrage ist es

1999-12-23T23:00:00.000Z

Was ich bisher versucht habe:

Ich habe { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } } zu meiner Komponente und zu meiner app.module.ts hinzugefügt. Das macht für mich keinen Unterschied.

Meine schmutzige Lösung (vor dem Senden der Anfrage):

 let newDate= new Date(this.personalForm.get("dateOfBirth").value);
 newDate.setMinutes(newDate.getMinutes() - newDate.getTimezoneOffset());

Wenn ich das mache, protokolliert die Konsole:

Wed Dec 24 1999 01:00:00 GMT+0100 (Mitteleuropäische Normalzeit)

und die Anfrage ist richtig:

1997-12-24T00:00:00.000Z

Aber wenn jetzt jemand aus einer anderen Zeitzone wie GMT-0100 wäre, würde das wieder nicht funktionieren. Wie kann man das richtig beheben?

Ich ändere den Adapter auch dynamisch, falls es notwendig ist zu wissen:

 this._adapter.setLocale(this.translateService.currentLang);

Antwort #1

Der Wert, der ausgewählt und angezeigt wird, ist derselbe... es sind die verschiedenen Formate des Datums-Zeit, die uns ein unterschiedliches Ergebnis zeigen (wobei sich auch das Datum ändert)!!

Zum Beispiel:

  • (standardmäßig): 2019-06-11T19:00:00.000Z
  • ist gleich (nach UTCString): Di., 11. Juni 2019 19:00:00 GMT
  • ist gleich (nach LocaleString): 12.06.2019, 00:00:00
  • entspricht (nach LocaleTimeString): 12:00:00 AM

Wir müssen es nicht konvertieren, weil das Datumsobjekt genau dieselbe Uhrzeit enthält.

Dieses Stackblitz wird weiterhin zeigen, welchen Unterschied ein Format an der Oberfläche machen kann, aber das Datum ist darunter dasselbe; Wenn Sie Fragen/Kommentare haben, können Sie dieses Stackblitz forken, Änderungen vornehmen und einen Kommentar zu dieser Antwort posten, ich werde versuchen, es zu klären.

relevant TS:

import {Component} from '@angular/core';

/** @title Basic datepicker */
@Component({
  selector: 'datepicker-overview-example',
  templateUrl: 'datepicker-overview-example.html',
  styleUrls: ['datepicker-overview-example.css'],
})
export class DatepickerOverviewExample {
  planModel: any = {start_time: new Date() };
  constructor(){}

  dateChanged(evt){
    let selectedDate = new Date(evt);
    console.log("by default:", selectedDate);
    console.log("by UTCString:", selectedDate.toUTCString());
    console.log("by LocaleString:", selectedDate.toLocaleString());
    console.log("by LocaleTimeString:", selectedDate.toLocaleTimeString());
  }

}

relevantes HTML:

<mat-form-field>
  <input matInput [matDatepicker]="picker" placeholder="Choose a date"
  [(ngModel)]="planModel.start_time"
  (ngModelChange)='dateChanged($event)'
  >
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

<hr/>

<p>By default: {{planModel.start_time}} </p>
<p>Medium date: {{planModel.start_time | date:'medium'}} </p>
<p>Short date: {{planModel.start_time | date:'short'}} </p>
<p>Short time: {{planModel.start_time | date: 'shortTime' }} </p>
<p>Medium time: {{planModel.start_time | date: 'mediumTime' }} </p>
<p>Long time: {{planModel.start_time | date: 'longTime' }} </p>
<p>Full time: {{planModel.start_time | date: 'fullTime' }} </p>

Antwort #2

Als Antwort auf Ihre eigene falsche Antwort…

23:00 UTC=00:00+01:00 am nächsten Tag (gleicher Moment)

Mi 24. Dez 1999 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit) aber in der Anfrage ist es

1999-12-23T23:00:00.000Z

Diese beiden Zeichenfolgen stellen denselben Wert dar. Sie sind zwei Möglichkeiten, denselben Moment zu betrachten. Die eine ist 23 Uhr UTC, die andere liegt eine Stunde vor UTC, also stellt sie den ersten Moment des nächsten Tages dar. Eine Stunde zu 23 Uhr am 23. in einem 24-Stunden-Tag hinzuzufügen, führt über den Mitternachtsstrich hinaus zum ersten Moment des 24.

Parsen

Analysiere deine Eingabezeichenkette als ein Instant. Das Z am Ende bedeutet UTC und wird „Zulu“ ausgesprochen. Ein Instant repräsentiert einen Moment in UTC, immer UTC, per Definition.

Ihr Eingabestring befindet sich im Standard-ISO-8601-Format. Die java.time-Klassen verwenden diese Standardformate standardmäßig beim Parsen/Generieren von Strings. Es ist also nicht nötig, ein Formatierungsmuster anzugeben.

Instant instant = Instant.parse( "1999-12-23T23:00:00.000Z" ) ;

Ein Moment (ein Datum, eine Tageszeit und eine zugewiesene Zeitzone oder ein Offset von UTC) muss in einer Datenbankspalte eines Typs gespeichert werden, der dem Standard-SQL-Typ TIMESTAMP WITH TIME ZONE ähnelt. Eine Spalte eines Typs, der TIMESTAMP WITHOUT TIME ZONE ähnelt, wäre der falsche Datentyp.

Um in Ihre Datenbank zu schreiben, müssen wir von der grundlegenden Bausteinklasse Instant auf die flexiblere Klasse OffsetDateTime wechseln. Die Unterstützung der Klasse OffsetDateTime in JDBC-Treibern wird ab JDBC 4.2 und später verlangt, während die Unterstützung von Instant optional ist.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ; 

Schreiben Sie in die Datenbank über ein PreparedStatement mit einem Platzhalter ?.

myPreparedStatement.setObject( … , odt ) ;

Abruf.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

Dies wurde auf Stack Overflow schon viele, viele Male diskutiert. Also suchen Sie, um mehr zu erfahren. Und bitte durchsuchen Sie Stack Overflow gründlich, bevor Sie etwas posten.

LocalDate

Wenn Ihr Ziel darin besteht, nur ein Datum zu verfolgen und Sie sich nicht wirklich für die Tageszeit und die Zeitzone interessieren, sollten Sie in Java LocalDate und in Standard-SQL eine DATE-Spalte verwenden.

Verwandte Artikel