Java時間計算:加減日期實現方法詳解

在日常開發中,無論是數據統計、活動倒計時、定時任務等都需要進行時間操作,其中一項常見的操作是加減日期,例如:將今天的日期往前或往後推幾天、幾個月、幾年,以及具體到某一天、某一時刻等。

一、Java 時間類

Java提供了一個處理日期和時間的類——Date,儘管它在Java SE 8中已經可以棄用使用,但是對於基礎知識的學習,介紹起來還是有必要的。

public class Date {
    /**
     * 分配給 Date 對象的唯一標識符。
     */
    private transient long fastTime;
    //...其他成員變量和方法
}

由上述代碼分析可知,Date 類利用一個「long型」的變量存儲日期時間信息,毫秒級別的時間戳可以完美地用long類型來表示,但是該類並沒有提供很好的時間計算方法。

二、Java Calendar 類

Java中的Calendar類是一個抽象類,提供了豐富的日期時間計算和轉換接口,由此也可以得出另一條結論:Java 預算日期操作最好使用 Calendar 類。

1. Calendar 類方法

Calendar 類提供的方法如下:

  • 根據日期設置年、月、日等時間信息。
  • 提供了獲取日期時間各部分信息的接口,如獲取年、月、日、小時、分鐘、秒等。
  • 提供了時間增減計算接口,如 add、roll 等方法。
  • Calendar 類提供了格式化日期的接口,例如,getDisplayName等。
  • Calendar 類提供了時區的操作接口。

其中 add 和 roll 方法都是時間增量計算方法,兩者的區別在於對於跨年的加減日期處理方式不同。

2. Calendar 類代碼示例

/**
 * 獲取某一天的開始時間
 *
 * @param calendar 時間對象
 * @return 當天起始時間
 */
public static Date getStartTimeOfDay(Calendar calendar) {
    Date date = calendar.getTime();
    try {
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0); 
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    } catch (Exception e) {
        log.error("", e);
    }
    return null;
}

上述代碼是獲取某一天的開始時間方法的實現,利用 Calendar 類的 getTime() 方法獲取當前時間,在設置成員變量中各部分時間為 0,即可得到當天開始時間。

三、時間計算區間工具類

為方便日後使用,我們通常會封裝一個工具類,來計算時間的加減和計算區間等。

1. 時間計算工具類代碼示例

/**
 * 時間計算工具類
 * 

* 包含獲取某一時間之前或之後的時間,以及計算時間區間等方法。 */public class DateUtil { /** * 指定時間加減年份 * * @param date 日期 * @param yearAmount 年數,正數代表往後推,負數代表往前推 * @return 計算完後的日期 */ public static Date addYear(Date date, int yearAmount) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.YEAR, yearAmount); return c.getTime(); } /** * 指定時間加減月份 * * @param date 日期 * @param monthAmount 月數,正數代表往後推,負數代表往前推 * @return 計算完後的日期 */ public static Date addMonth(Date date, int monthAmount) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MONTH, monthAmount); return c.getTime(); } /** * 指定時間加減天數 * * @param date 日期 * @param dayAmount 日數,正數代表往後推,負數代表往前推 * @return 計算完後的日期 */ public static Date addDay(Date date, int dayAmount) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.DAY_OF_MONTH, dayAmount); return c.getTime(); } /** * 指定時間加減小時數 * * @param date 日期 * @param hourOfdayAmount 小時數,正數代表往後推,負數代表往前推 * @return 計算完後的日期 */ public static Date addHourOfDay(Date date, int hourOfdayAmount) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.HOUR_OF_DAY, hourOfdayAmount); return c.getTime(); } /** * 指定時間加減分鐘數 * * @param date 日期 * @param minuteAmount 分鐘數,正數代表往後推,負數代表往前推 * @return 計算完後的日期 */ public static Date addMinute(Date date, int minuteAmount) { Calendar c = Calendar.getInstance(); c.setTime(date); c.add(Calendar.MINUTE, minuteAmount); return c.getTime(); }

上述代碼通過 Calendar 類提供的 add 方法,對時間的年、月、日、時、分等信息進行加減,從而實現時間操作的目的。

2. 時間區間計算代碼示例

/**
 * 時間區間計算工具類
 * 

* 如果 startTime 為null,endTime 不為null,則返回endTime到當前的區間列表。 * 如果 endTime 為null,startTime 不為null,則返回startTime到當前的區間列表。 * 如果 startTime 和 endTime 都為null,則返回全年或全月或全日的區間列表。 * * @param startTime 開始日期 * @param endTime 結束日期 * @return 時間區間列表 */public static List getTimeInterval(String startTime, String endTime) throws Exception { if ((startTime == null || startTime.trim().equals("")) && (endTime == null || endTime.trim().equals(""))) { throw new Exception("開始時間和結束時間不能同時為空!"); } List result = new ArrayList(); SimpleDateFormat sdf = null; DateTimeFormatter formatter = null; String datePattern = ""; LocalDateTime nowLdt = LocalDateTime.now(); LocalDateTime startLdt = null; LocalDateTime endLdt = null; Integer year = null; Integer month = null; if (!StringUtils.isEmpty(startTime)) { datePattern = getPattern(startTime); if (datePattern == null || datePattern.equals("")) { throw new Exception("開始時間格式錯誤!(yyyy-MM-dd或yyyy-MM-dd HH:mm:ss)"); } //解決java.time.DateTimeParseException異常問題 formatter = DateTimeFormatter.ofPattern(datePattern); startLdt = LocalDateTime.parse(startTime, formatter); year = startLdt.getYear(); month = startLdt.getMonth().getValue(); } if (!StringUtils.isEmpty(endTime)) { datePattern = getPattern(endTime); if (datePattern == null || datePattern.equals("")) { throw new Exception("結束時間格式錯誤!(yyyy-MM-dd或yyyy-MM-dd HH:mm:ss)"); } //解決java.time.DateTimeParseException異常問題 formatter = DateTimeFormatter.ofPattern(datePattern); endLdt = LocalDateTime.parse(endTime, formatter); year = endLdt.getYear(); month = endLdt.getMonth().getValue(); } int startYear = year == null ? nowLdt.getYear() : year; int endYear = year == null ? nowLdt.getYear() : year; int startMon = month == null ? nowLdt.getMonthValue() : month; int endMon = month == null ? nowLdt.getMonthValue() : month; if (startLdt != null) { startYear = startLdt.getYear(); startMon = startLdt.getMonthValue(); } if (endLdt != null) { endYear = endLdt.getYear(); endMon = endLdt.getMonthValue(); } if (startLdt != null && endLdt != null && startLdt.isBefore(nowLdt) && endLdt.isAfter(nowLdt)) { startYear = nowLdt.getYear(); startMon = nowLdt.getMonthValue(); } for (int yearIndex = startYear; yearIndex endMon) || (startYear nowLdt.getMonthValue())) { break; } int startMonIndex = 1; int endMonIndex = 12; if (yearIndex == startYear && yearIndex == endYear) { startMonIndex = startMon; endMonIndex = endMon; } else if (yearIndex == startYear) { startMonIndex = startMon; } else if (yearIndex == endYear) { endMonIndex = endMon; } for (int monIndex = startMonIndex; monIndex <= endMonIndex; monIndex++) { LocalDate localDate = LocalDate.of(yearIndex, monIndex, 1); int maxDaysOfMonth = localDate.lengthOfMonth(); String startTimeStr = ""; String endTimeStr = ""; if (startLdt != null && startLdt.getYear() == yearIndex && startLdt.getMonthValue() == monIndex) { startTimeStr = startTime; } else { startTimeStr = yearIndex + "-" + formatNumber(monIndex) + "-01 00:00:00"; } if (endLdt != null && endLdt.getYear() == yearIndex && endLdt.getMonthValue() == monIndex) { endTimeStr = endTime; } else { endTimeStr = yearIndex + "-" + formatNumber(monIndex) + "-" + maxDaysOfMonth + " 23:59:59"; } result.add(startTimeStr + "|" + endTimeStr); } } return result;}private static String getPattern(String date) { if (date.contains("-")) { return date.contains(":") ? "yyyy-MM-dd HH:mm:ss" : "yyyy-MM-dd"; } else if (date.contains("/")) { return date.contains(":") ? "yyyy/MM/dd HH:mm:ss" : "yyyy/MM/dd"; } return "";}private static String formatNumber(int value) { return value < 10 ? "0" + value : String.valueOf(value);}

上述代碼中演示了時間區間計算的示例。根據輸入的開始時間和結束時間,計算出時間區間列表。例如,在輸入 2019-06-01 和 2019-07-01 時,輸出「2019-06-01 00:00:00|2019-06-30 23:59:59」、「2019-07-01 00:00:00|2019-07-01 23:59:59」兩個時間區間。

四、總結

時間計算在日常開發中是經常遇到的任務,Java 中提供了多種計算日期的方法和類。其中,我們建議使用 Calendar 類,實現增減日期,包含了較為豐富的接口。此外,為方便使用和復用,我們可以封裝一個時間計算工具類,增加代碼復用性。

原創文章,作者:FKBVW,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/334045.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FKBVW的頭像FKBVW
上一篇 2025-02-05 13:05
下一篇 2025-02-05 13:05

相關推薦

  • Python計算陽曆日期對應周幾

    本文介紹如何通過Python計算任意陽曆日期對應周幾。 一、獲取日期 獲取日期可以通過Python內置的模塊datetime實現,示例代碼如下: from datetime imp…

    編程 2025-04-29
  • 解決docker-compose 容器時間和服務器時間不同步問題

    docker-compose是一種工具,能夠讓您使用YAML文件來定義和運行多個容器。然而,有時候容器的時間與服務器時間不同步,導致一些不必要的錯誤和麻煩。以下是解決方法的詳細介紹…

    編程 2025-04-29
  • Python獲取當前日期的多種方法

    本文介紹如何使用Python獲取當前日期,並提供了多種方法,包括使用datetime模塊、time模塊以及第三方庫dateutil等。讓我們一步一步來看。 一、使用datetime…

    編程 2025-04-29
  • 想把你和時間藏起來

    如果你覺得時間過得太快,每天都過得太匆忙,那麼你是否曾經想過想把時間藏起來,慢慢享受每一個瞬間?在這篇文章中,我們將會從多個方面,詳細地闡述如何想把你和時間藏起來。 一、一些時間管…

    編程 2025-04-28
  • Python按照日期畫折線圖

    本文將為您詳細介紹如何使用Python按照日期(時間)來畫折線圖。 一、準備工作 首先,我們需要安裝Matplotlib包,該包提供了各種繪圖函數,包括折線圖、柱形圖、散點圖等等。…

    編程 2025-04-28
  • 計算斐波那契數列的時間複雜度解析

    斐波那契數列是一個數列,其中每個數都是前兩個數的和,第一個數和第二個數都是1。斐波那契數列的前幾項為:1,1,2,3,5,8,13,21,34,…。計算斐波那契數列常用…

    編程 2025-04-28
  • 時間戳秒級可以用int嗎

    時間戳是指從某個固定的時間點開始計算的已經過去的時間。在計算機領域,時間戳通常使用秒級或毫秒級來表示。在實際使用中,我們經常會遇到需要將時間戳轉換為整數類型的情況。那麼,時間戳秒級…

    編程 2025-04-28
  • 如何在ACM競賽中優化開發時間

    ACM競賽旨在提高程序員的算法能力和解決問題的實力,然而在比賽中優化開發時間同樣至關重要。 一、規劃賽前準備 1、提前熟悉比賽規則和題目類型,了解常見算法、數據結構和快速編寫代碼的…

    編程 2025-04-28
  • Python如何輸入日期

    Python是一種非常流行的編程語言,它可以讓開發人員輕鬆地處理日期時間。在本文中,我們將詳細介紹Python如何輸入日期的方法,無論您是在處理日期時間的數據分析還是在創建Web應…

    編程 2025-04-28
  • 使用JavaScript日期函數掌握時間

    在本文中,我們將深入探討JavaScript日期函數,並且從多個視角介紹其應用方法和重要性。 一、日期的基本表示與獲取 在JavaScript中,使用Date對象來表示日期和時間,…

    編程 2025-04-28

發表回復

登錄後才能評論