亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從 MySQL DB 中選擇后的日期向后一天

從 MySQL DB 中選擇后的日期向后一天

森林海 2022-06-15 17:50:40
我有時區相關的問題。我在 JAVA 和 MySql 數據庫中有一個程序。我不使用任何 ORM,但我有使用 mysql 連接器 java v 6.0.4 的自定義 jdbc 庫我將設置作為連接字符串的一部分發送為: serverTimezone - America/Chicago useTimezone - true useJDBCCompliantTimezoneShift - false useLegacyDatetimeCode - false我嘗試從數據庫中選擇一個日期,例如2019-02-13。數據庫位于美國/東部時區,運行 java 程序的服務器位于美國/芝加哥時區。無法更改任何服務器的位置/時區。在 Java 中,我得到一個倒退一天的日期(2019-02-12)。問題是由于時間戳引起的 -1550034000在2019-02-13 00:00:00美國/東部但1550034000在2019-02-12 23:00:00美國/芝加哥所以結果我有java.sql.Datedate 對象2019-02-12。添加時區偏移沒有任何幫助,因為時間信息與日期截斷。您能否就如何在沒有時區偏移的情況下獲得正確的日期提出一些解決方案?編輯:我正在使用serverTimezone設置,但我不確定值是否應該是數據庫正在使用的時區,或者它只是覆蓋運行應用程序的 JVM/服務器的時區。
查看完整描述

2 回答

?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

首先,我讀到您的情況不能,但對于其他讀者,我想說明一般建議是在 UTC 中運行所有內容,至少當您跨越多個時區時。因此,這將是解決您問題的最佳方法。


其次,正如我和 Gord Thompson 在評論中提到的那樣,第二個最佳解決方案是將日期處理為LocalDate,而不是java.sql.Date. 雖然后者只是假裝沒有時間,但它確實存在設計問題,難以解決您的問題。ALocalDate真的是一個沒有時間和時區的日期,所以應該是一個更安全的賭注(除了LocalDate已經聽說過錯誤轉換的數據庫驅動程序;我保持手指交叉;再次運行一切UTC 也會消除這些錯誤)。編輯:假設您可以修改自定義 JDBC 庫,以下是如何LocalDate從 a 獲取 a ResultSet:


    LocalDate correctDateDirectlyFromDatabase

            = yourResultSet.getObject("yourDateColumn", LocalDate.class);

它至少需要 JDBC 4.2,你可能有。


如果您無法獲得上述任何一項,那么可以通過以下方法來修正Date您從數據庫中獲得的錯誤信息。這有點駭人聽聞,但會起作用。


import java.sql.Date;


// …


    // Modern ID of the time zone previously known as US/Eastern

    ZoneId datebaseTimeZone = ZoneId.of("America/New_York");


    Date dateFromDatabase = new Date(TimeUnit.SECONDS.toMillis(1_550_034_000));

    System.out.println("Date as retrieved from database (or pretending): " + dateFromDatabase);


    long epochMillis = dateFromDatabase.getTime();

    ZonedDateTime dateTime = Instant.ofEpochMilli(epochMillis)

            .atZone(datebaseTimeZone);

    LocalDate realDate = dateTime.toLocalDate();

    // Sanity check

    if (! realDate.atStartOfDay(datebaseTimeZone).equals(dateTime)) {

        throw new IllegalStateException("Failed to convert date correctly from " + datebaseTimeZone + " time zone");

    }


    System.out.println("Date is " + realDate);

當我在美國/芝加哥時區運行它時,它打?。?/p>


Date as retrieved from database (or pretending): 2019-02-12

Date is 2019-02-13

我試過在其他時區運行它。在某些時區,第一行打印2019-02-12,在其他時區2019-02-13。最后一行打印2019-02-13在我嘗試過的所有時區。


現在我給了你一個LocalDate. 很好,這是您在進一步處理中應該使用的。如果您需要java.sql.Date另一個您不想更改的舊 API,請通過以下方式轉換回正確 java.sql.Date的 API :


    Date oldfashionedJavaSqlDate = Date.valueOf(realDate);

    System.out.println("Date converted back to " + oldfashionedJavaSqlDate);

日期轉換回 2019-02-13


當我說正確時,它要求沒有人篡改您的 JVM 的默認時區,這對于任何在 JVM 中運行的程序來說都很容易做到。


查看完整回答
反對 回復 2022-06-15
?
一只斗牛犬

TA貢獻1784條經驗 獲得超2個贊

我正在使用serverTimezone設置,但我不確定值是否應該是數據庫正在使用的時區,或者它只是覆蓋運行應用程序的 JVM/服務器的時區。

serverTimezone=America/Chicago意思是“解釋來自服務器的結果,就像服務器正在使用America/Chicago時區一樣,而不管服務器配置為使用的默認時區如何”。因此,如果您在連接字符串中使用該設置,Timestamp即使America/Chicago服務器的默認時區顯然是America/New_York.

但是,在采用這種方法之前,您需要確認服務器確實在使用America/New_York(這可能會在東部標準時間和東部夏令時間之間來回切換)而不是像 UTC-5 這樣的固定偏移量(它將始終保持不變)在“東部標準時間”)。


查看完整回答
反對 回復 2022-06-15
  • 2 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號