Je sais qu'il y a plusieurs discussions à ce sujet et je les ai toutes lues mais je n'ai pas pu résoudre ce problème pendant des jours. Je pourrais trouver une solution, mais elle semble être sale pour moi.
Donc, comme d'autres utilisateurs, j'ai le même problème avec le datePicker. Pour moi, c'est le Angular Material Datepicker mat-datepicker
Lorsque j'enregistre la valeur, j'obtiens le résultat correct:
Wed Dec 24 1999 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit)
mais dans la demande c'est
1999-12-23T23:00:00.000Z
Ce que j'ai encore essayé:
J'ai ajouté { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
à mon component
et à mon app.module.ts
. Cela ne fait aucune différence pour moi.
Ma sale solution (avant d'envoyer la demande):
let newDate= new Date(this.personalForm.get("dateOfBirth").value);
newDate.setMinutes(newDate.getMinutes() - newDate.getTimezoneOffset());
Lorsque je fais cela, les journaux de la console:
Wed Dec 24 1999 01:00:00 GMT+0100 (Mitteleuropäische Normalzeit)
et la demande est juste:
1997-12-24T00:00:00.000Z
Mais si quelqu'un venait maintenant d'un fuseau horaire différent comme GMT-0100, cela ne fonctionnerait plus. Comment résoudre ce problème correctement?
Je change également l'adaptateur dynamiquement s'il est nécessaire de savoir:
this._adapter.setLocale(this.translateService.currentLang);
En réponse à votre propre réponse incorrecte …
Mer 24 déc 1999 00:00:00 GMT + 0100 (Mitteleuropäische Normalzeit) mais dans la demande il est
1999-12-23T23: 00: 00.000Z
Ces deux chaînes représentent la même valeur. Ce sont deux façons de voir le même moment. L'un est 11 PM à UTC, l'autre a une heure d'avance sur UTC, il représente donc le premier moment du lendemain. Ajouter une heure à 11 PM = le 23 d'une journée de 24 heures passe le coup de minuit au premier moment du 24.
Analysez votre chaîne d'entrée en tant que Instant
. Le Z à la fin signifie UTC et se prononce "Zulu". Un Instant
représente un moment en UTC, toujours UTC, par définition.
Votre chaîne d'entrée est au format standard ISO 8601. Les classes Java.time utilisent par défaut ces formats standard lors de l'analyse/génération de chaînes. Il n'est donc pas nécessaire de spécifier un modèle de formatage.
Instant instant = Instant.parse( "1999-12-23T23:00:00.000Z" ) ;
Un moment (une date, une heure et un fuseau horaire ou décalage par rapport à UTC) doit être enregistré dans une colonne de base de données d'un type semblable au type SQL standard TIMESTAMP WITH TIME ZONE
. Une colonne d'un type semblable à TIMESTAMP WITHOUT TIME ZONE
serait le type de données incorrect .
Pour écrire dans votre base de données, nous devons passer de la classe de base du bloc de construction de Instant
à la classe plus flexible OffsetDateTime
. La prise en charge de la classe OffsetDateTime
dans les pilotes JDBC est requise par JDBC 4.2 et versions ultérieures, tandis que la prise en charge Instant
est facultative.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Ecrire dans la base de données via un PreparedStatement
avec un espace réservé ?
.
myPreparedStatement.setObject( … , odt ) ;
Récupération.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Cela a été discuté plusieurs fois sur Stack Overflow. Recherchez donc pour en savoir plus. Et veuillez rechercher à fond Stack Overflow avant de poster.
LocalDate
Si votre objectif est de suivre uniquement une date et que vous ne vous souciez pas vraiment de l'heure et du fuseau horaire, vous devez utiliser LocalDate
in Java and DATE
colonne en SQL standard.
À la fin, le problème était dans mon backend et devait comprendre ce qui se passait.
Pour enregistrer la date directement dans ma base de données Postgres:
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);
LocalDateTime lu = LocalDateTime.parse(lastUpdated, inputFormatter);
LocalDateTime dob = LocalDateTime.parse(dateOfBirth, inputFormatter);
this.dateOfBirth = Date.from(dob.atZone(ZoneOffset.UTC).toInstant());
this.lastUpdated = Date.from(lu.atZone(ZoneOffset.UTC).toInstant());
Avant je
this.dateOfBirth = Date.from(dob.atZone(ZoneId.systemDefault()).toInstant());
ce qui était faux. Je viens de recevoir la demande telle qu'elle est donnée par Angular et Java l'enregistre directement dans la base de données.
1999-12-23T23:00:00.000Z
se transforme en
1997-12-24 00:00:00
Haha, ma sale solution pour cela était cette méthode, qui fait son travail pour ce qu'elle est, car je voulais juste renvoyer la date sous forme de chaîne sans aucune autre information, qui serait mappée à un objet datetime dans le backend et enregistrée ...
public setDate(date: any): string {
const chosenDate = new Date(date);
return `${chosenDate.getMonth() + 1}/${chosenDate.getDate()}/${chosenDate.getFullYear()}`;
}
puis définissez la valeur de l'objet dans le html
<mat-form-field appearance="outline">
<mat-label>Birthdate</mat-label>
<input matInput [matDatepicker]="birthdatePicker" placeholder="Birthdate"
(dateChange)="user.birthdate = setDate($event.value)">
<mat-datepicker-toggle matSuffix [for]="birthdatePicker"></mat-datepicker-toggle>
<mat-datepicker #birthdatePicker></mat-datepicker>
<mat-error>error</mat-error>
</mat-form-field>