首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 中獲取午夜 00:00:00 格式 Timestamp 的正確姿勢

     編輯:Java 相關知識

前言

在 Java 開發中,經常需要獲取當天零點(00:00:00)的 Timestamp,例如用於資料庫查詢的時間範圍起始值。乍看之下只是格式化輸出,但若忽略時區偏移,極易踩坑。本文將示範如何正確獲取午夜 Timestamp,並解析時區對結果的影響。

核心程式碼示範

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.TimeZone;

public class MidnightTimestampDemo {
    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long now = System.currentTimeMillis();

        // 錯誤示範:直接對 86400000 取模,未考慮時區
        long t1 = now / (1000 * 3600 * 24) * (1000 * 3600 * 24);
        System.out.println("未扣時區偏移: " + sdf.format(new Timestamp(t1)));

        // 正確做法:扣除當地時區原始偏移量
        long t2 = now / (1000 * 3600 * 24) * (1000 * 3600 * 24) 
                - TimeZone.getDefault().getRawOffset();
        System.out.println("扣除時區偏移: " + sdf.format(new Timestamp(t2)));
    }
}

關鍵點解析

1. 為什麼要除以 86400000 再乘回去?

1000 * 3600 * 24 = 86,400,000 毫秒,即一天的總毫秒數。對當前時間戳進行整除再乘回,可將時間「對齊」到最近的午夜基準點(UTC 1970-01-01 00:00:00 起算的整天倍數)。

2. 時區偏移為何物?

TimeZone.getDefault().getRawOffset() 回傳當地時區相對 UTC 的固定偏移毫秒數(不含夏令時)。若不扣除,輸出會是 UTC 零點對應的本地時間。例如東八區(GMT+8)會顯示為 08:00:00,而非預期的 00:00:00。

3. 更優雅的現代寫法(Java 8+)

import java.time.LocalDate;
import java.time.ZoneId;
import java.sql.Timestamp;

public class ModernMidnight {
    public static void main(String[] args) {
        // 直接獲取今天零點的 Timestamp,自動處理時區
        Timestamp midnight = Timestamp.valueOf(LocalDate.now().atStartOfDay());
        System.out.println("Java 8 寫法: " + midnight); // 2024-05-20 00:00:00.0
    }
}

LocalDate.now().atStartOfDay() 會依據系統預設時區產生當天 00:00:00 的 LocalDateTime,再轉為 Timestamp 即可,程式碼更簡潔且不易出錯。

總結

  • 舊版 Java 需手動計算毫秒數並扣除 TimeZone.getRawOffset()。
  • Java 8 起請優先使用 java.time 套件,語意清晰且自動處理時區。
  • 儲存資料庫時,建議統一使用 UTC 時間戳,顯示層再按使用者時區格式化。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved