web-dev-qa-db-ja.com

Angular重要な日付ピッカー:1日前の日付解析UTC問題

私はこれについていくつかのスレッドがあることを知っています、そして私はそれらすべてを読みましたが、数日間これを修正することができませんでした。私は解決策を見つけるかもしれませんが、それは私にとって汚いようです。

他のユーザーと同じように、datePickerにも同じ問題があります。私にとってはAngular Material Datepicker mat-datepicker

値を記録すると、正しい結果が得られます。

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

しかし、リクエストでは

1999-12-23T23:00:00.000Z

私がまだ試したこと:

私は追加しました { provide: MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }自分のcomponentと自分のapp.module.ts。それは私にとって何の違いもありません。

私の汚い解決策(リクエストを送信する前):

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

これを実行すると、コンソールがログに記録します。

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

そしてリクエストは正しいです:

1997-12-24T00:00:00.000Z

しかし、誰かがGMT-0100のような別のタイムゾーンにいる場合、これは再び機能しません。これを正しく修正する方法は?

知る必要がある場合は、アダプタも動的に変更します。

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

あなた自身の間違った答え …への応答

11 PM UTC = 00:00 + 01:00翌日(同じ瞬間)

1999年12月24日水曜日00:00:00 GMT + 0100(MitteleuropäischeNormalzeit)しかし、リクエストでは

1999-12-23T23:00:00.000Z

これら2つの文字列は同じ値を表します。同じ瞬間を見る2つの方法です。 1つは11 PM、もう1つはUTCより1時間進んでいるため、翌日の最初の瞬間を表しています。11に1時間を追加するPM = 24時間の長い日の23日は、真夜中のストロークを過ぎて、24日の最初の瞬間まで続きます。

解析中

入力文字列をInstantとして解析します。末尾のZはUTCを意味し、「ズールー」と発音されます。 Instantは、定義により、UTC、常にUTCの瞬間を表します。

入力文字列は標準のISO 8601形式です。 Java.timeクラスは、文字列の解析/生成時にデフォルトでこれらの標準形式を使用します。したがって、フォーマットパターンを指定する必要はありません。

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

瞬間(日付、時刻、および割り当てられたタイムゾーンまたはUTCからのオフセット)は、標準SQLタイプTIMESTAMP WITH TIME ZONEに類似したタイプのデータベース列に保存する必要があります。 TIMESTAMP WITHOUT TIME ZONEに類似した型の列は、wrongデータ型になります。

データベースに書き込むには、Instantの基本的なビルディングブロッククラスから、より柔軟なOffsetDateTimeクラスに切り替える必要があります。 JDBC 4.2以降では、JDBCドライバーのOffsetDateTimeクラスのサポートが必要ですが、Instantサポートはオプションです。

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

プレースホルダー?を使用してPreparedStatement経由でデータベースに書き込みます。

myPreparedStatement.setObject( … , odt ) ;

検索。

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

これはスタックオーバーフローで何度も議論されてきました。詳細については、検索してください。投稿する前に、Stack Overflowを徹底的に検索してください。

LocalDate

日付のみを追跡することが目標であり、時刻とタイムゾーンに特に関心がない場合は、LocalDate in Java and DATE標準SQLの列。

0
Basil Bourque

最後に問題は私のバックエンドにあり、何が起こっているのかを理解する必要がありました。

日付を自分の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());

私が持っていた前に

 this.dateOfBirth = Date.from(dob.atZone(ZoneId.systemDefault()).toInstant()); 

それは間違っていました。 Angular and Javaはそれをデータベースに直接保存します。

1999-12-23T23:00:00.000Z 

になる

1997-12-24 00:00:00
0
CptDayDreamer

ハハ、このための私の汚い解決策はこの方法でした、それはそれが何であるかという仕事です...

public setDate(date: any): string {
    const chosenDate = new Date(date);
    return `${chosenDate.getMonth() + 1}/${chosenDate.getDate()}/${chosenDate.getFullYear()}`;
}

そして、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>
0
Noob