iT邦幫忙

0

應用系統建置前準備工具 - DateUtils 日期工具

  • 分享至 

  • xImage
  •  

DateUtils 日期工具類別

概述

DateUtils 是一個用於處理日期時間的工具類別,提供日期格式轉換、計算與驗證等功能。此類別設計為靜態工具類別,特別支援民國曆與西元曆的互轉,以及多種常用日期格式的處理。

專案相關程式

  • GlobalConstants

第三方元件(Dependency)

  • org.apache.commons.lang3

主要功能

1. 日期時間取得

目前時間

// 取得目前日期時間
Date now = DateUtils.dateTimeNow();

// 取得目前日期時間字串(預設格式:yyyy-MM-dd HH:mm:ss)
String nowStr = DateUtils.dateTimeNowString();

// 取得目前日期字串(預設格式:yyyyMMdd)
String todayStr = DateUtils.dateNowString();

自訂格式

// 指定格式取得目前時間
String dateStr = DateUtils.dateTimeNowString("yyyy/MM/dd");  // "2025/11/08"
String timeStr = DateUtils.dateTimeNowString("HH:mm:ss");    // "14:30:00"

2. 日期格式轉換

日期物件轉字串

// 日期轉指定格式字串
Date date = new Date();
String formatted = DateUtils.dateTimeToString(date, "yyyy-MM-dd");  // "2025-11-08"

字串轉日期物件

// 將字串轉換為日期物件
Date date = DateUtils.stringToDate("2025-11-08", "yyyy-MM-dd");

// 使用預設格式(yyyy-MM-dd HH:mm:ss)
Date datetime = DateUtils.stringToDate("2025-11-08 14:30:00");

3. 日期計算

日期差異計算

// 計算兩個日期之間的天數
long days = DateUtils.daysBetweenDate(startDate, endDate);

// 計算兩個日期之間的月數
long months = DateUtils.monthsBetweenDate(startDate, endDate);

// 計算兩個日期之間的年數
long years = DateUtils.yearsBetweenDate(startDate, endDate);

日期位移

// 日期加減計算
Date today = new Date();
Date tomorrow = DateUtils.getOffsetDate(today, 1, Calendar.DATE);     // 加一天
Date nextMonth = DateUtils.getOffsetDate(today, 1, Calendar.MONTH);   // 加一個月
Date nextYear = DateUtils.getOffsetDate(today, 1, Calendar.YEAR);     // 加一年

4. 民國年轉換

西元年轉民國年

// 西元年轉民國年(yyyyMMdd 轉 yyyMMdd)
String minguoDate = DateUtils.transferADDateToMinguoDate(new Date());  // "1121108"

民國年轉西元年

// 民國年轉西元年(yyyMMdd 轉 yyyyMMdd)
String adDate = DateUtils.transferMinguoDateToADDate("1121108");  // "20231108"

5. 其他功能

日期格式驗證

// 驗證日期字串格式
boolean isValid = DateUtils.isValidDate("2025-11-08", "yyyy-MM-dd");     // true
boolean notValid = DateUtils.isValidDate("2025-13-08", "yyyy-MM-dd");    // false

Julian Date 計算

// 計算一年中的第幾天
String julianDate = DateUtils.julianDate(new Date());  // "312" (11月8日)

重要注意事項

  1. 格式處理

    • 支援多種日期格式模式(yyyy-MM-dd、yyyyMMdd等)
    • 使用預設格式時間格式:yyyy-MM-dd HH:mm:ss
    • 使用預設日期格式:yyyyMMdd
  2. 日期轉換

    • 格式錯誤時返回 null
    • 轉換失敗時會記錄例外
    • 民國年轉換需要 Java 8 以上版本

單元測試範例

以下測試範例示範 DateUtils 常見功能與邊界情況:

1. 目前時間與格式化

@Test
void testDateTimeNowString() {
   String now = DateUtils.dateTimeNowString();
   assertNotNull(now);
   assertTrue(now.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}"));
}

2. 字串轉日期與格式轉換

@Test
void testStringToDateAndBack() {
   String src = "2025-11-08 14:30:00";
   Date d = DateUtils.stringToDate(src, "yyyy-MM-dd HH:mm:ss");
   assertNotNull(d);
   String formatted = DateUtils.dateTimeToString(d, "yyyy-MM-dd HH:mm:ss");
   assertEquals(src, formatted);
}

3. 日期差異與位移

@Test
void testDaysBetweenAndOffset() {
   Date today = DateUtils.stringToDate("2025-11-08", "yyyy-MM-dd");
   Date tomorrow = DateUtils.getOffsetDate(today, 1, Calendar.DATE);
   long days = DateUtils.daysBetweenDate(today, tomorrow);
   assertEquals(1, days);
}

4. 民國年轉換與驗證

@Test
void testMinguoConversionAndValidation() {
   String minguo = DateUtils.transferADDateToMinguoDate(
      DateUtils.stringToDate("2025-11-08", "yyyy-MM-dd"));
   assertNotNull(minguo);
   String ad = DateUtils.transferMinguoDateToADDate(minguo);
   assertEquals("20251108", ad);

   assertTrue(DateUtils.isValidDate("2025-11-08", "yyyy-MM-dd"));
   assertFalse(DateUtils.isValidDate("2025-13-08", "yyyy-MM-dd"));
}

測試說明

  • 測試格式化/解析互相轉換
  • 測試日期位移與差異計算
  • 測試民國/西元轉換與格式驗證
  1. 計算功能

    • 日期差異計算含起始日
    • 月份計算考慮不同月份天數
    • 時間位移支援分鐘到年的單位
  2. 輸入驗證

    • 自動處理 null 或空字串輸入
    • 嚴格檢查日期有效性
    • 支援閏年判斷

程式碼 DateUtils.java

package tw.lewishome.webapp.base.utility.common;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.chrono.ChronoLocalDate;
import java.time.chrono.Chronology;
import java.time.chrono.MinguoChronology;
import java.time.chrono.MinguoDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DecimalStyle;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import org.apache.commons.lang3.StringUtils;

/**
 * 日期工具類,提供多種日期格式轉換、日期運算、民國曆與西元曆互轉等功能。
 *
 * 支援常用日期格式字串定義、日期字串與 {@link java.util.Date} 物件互轉、日期加減運算、
 * 檢查日期格式合法性、取得民國曆與西元曆轉換、計算兩日期間天數等。
 *
 * <h2>常用格式</h2>
 * <ul>
 * <li>YYYY = "yyyy"</li>
 * <li>YYYY_MM = "yyyy-MM"</li>
 * <li>YYYY_MM_DD = "yyyy-MM-dd"</li>
 * <li>YYYYMDD = "yyyyMMdd"</li>
 * <li>YYYYMMDDHHMMSS = "yyyyMMddHHmmss"</li>
 * <li>YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"</li>
 * </ul>
 * <h2>主要功能</h2>
 * <ul>
 * <li>取得目前日期時間(Date 或字串格式)</li>
 * <li>將日期物件轉換為指定格式字串</li>
 * <li>將日期字串轉換為日期物件</li>
 * <li>檢查日期字串是否合法</li>
 * <li>計算一年中的第幾天(Julian Date)</li>
 * <li>日期加減(天、月、年等)</li>
 * <li>民國曆與西元曆互轉</li>
 * <li>計算兩日期間相差天數</li>
 * </ul>
 * 
 * <h2>注意事項</h2>
 * <ul>
 * <li>部分方法依賴 {@code org.apache.commons.lang3.StringUtils}。</li>
 * <li>民國曆轉換需 Java 8 以上,使用 {@code java.time.chrono.MinguoChronology}。</li>
 * <li>日期格式錯誤時,部分方法會回傳 {@code null}。</li>
 * </ul>
 *
 * @author Lewis
 * @version 1.0
 */
public class DateUtils {
   /** Private constructor to prevent instantiation */
    private DateUtils() {
        throw new IllegalStateException("This is a utility class and cannot be instantiated");
    }

    /** Constant <code>YYYY="yyyy"</code> */
    public static final String YYYY = "yyyy";

    /** Constant YYYYMM Under Line Delimiter */
    public static final String YYYY_MM_UNDER_LINE = "yyyy_MM";
    /** Constant YYYYMM Slash Delimiter */
    public static final String YYYY_MM_SLASH = "yyyy/MM";
    /** Constant YYYYMM Dash Delimiter */
    public static final String YYYY_MM_DASH = "yyyy-MM";
    /** Constant YYYYMM Dot Delimiter */
    public static final String YYYY_MM_DOT = "yyyy.MM";
    /** Constant YYYYMM None Delimiter */
    public static final String YYYYMM = "yyyyMM";

    /** Constant yyyy_MM_dd Dash Delimiter */
    public static final String YYYY_MM_DD_UNDER = "yyyy_MM_dd";
    /** Constant yyyy/MM/dd Slash Delimiter */
    public static final String YYYY_MM_DD_SLASH = "yyyy/MM/dd";
    /** Constant yyyy-MM-dd Dash Delimiter */
    public static final String YYYY_MM_DD_DASH = "yyyy-MM-dd";
    /** Constant yyy.MM.dd Dot Delimiter */
    public static final String YYYY_MM_DD_DOT = "yyyy.MM.dd";
    /** Constant yyyy:MM:dd" Semicolon Delimiter */
    public static final String YYYY_MM_DD_SEMICOLON = "yyyy:MM:dd";
    /** Constant YYYYMMDD None Delimiter */
    public static final String YYYYMMDD = "yyyyMMdd";

    /** Constant <code>YYYYMMDDHHMMSS="yyyyMMddHHmmss"</code> */
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    /** Constant DateTime (yyyy-MM-dd HH:mm:ss) Dash Delimiter */
    public static final String YYYY_MM_DD_HH_MM_SS_DASH = "yyyy-MM-dd HH:mm:ss";
    /** Constant DateTime (yyyy_MM_dd HH:mm:ss) Under Line Delimiter */
    public static final String YYYY_MM_DD_HH_MM_SS_UNDER_LINE = "yyyy_MM_dd HH:mm:ss";
    /** Constant DateTime (yyyy/MM/dd HH:mm:ss) Slash Delimiter */
    public static final String YYYY_MM_DD_HH_MM_SS_SLASH = "yyyy/MM/dd HH:mm:ss";
    /** Constant DateTime (yyyy.MM.dd HH:mm:ss) Dot Delimiter */
    public static final String YYYY_MM_DD_HH_MM_SS_DOT = "yyyy.MM.dd HH:mm:ss";
    /** Constant DateTime (yyyy:MM:dd HH:mm:ss) Semicolon Delimiter */
    public static final String YYYY_MM_DD_HH_MM_SS_SEMICOLON = "yyyy:MM:dd HH:mm:ss";
    /** Constant DateTime (yyyyMMdd HHmmss) None Delimiter */
    public static final String YYYYMMDDHHMMSS_NONE = "yyyyMMdd HHmmss";

    /** Constant HH:mm:ss:SSSSS 時分秒毫秒 */
    public static final String TIME_HH_MM_SS_Z = "HH:mm:ss.SSSSSS";
    /** Constant HH:mm:ss:SSSSS 時分秒毫秒 None delimiter */
    public static final String TIME_HHMMSSZ = "HHmmssSSSSSS";
    /** Constant HH:mm:ss 時分秒 */
    public static final String TIME_HH_MM_SS = "HH:mm:ss";
    /** Constant HH:mm:ss 時分秒 None delimiter */
    public static final String TIME_HHMMSS = "HHmmss";
    /** Constant HH:mm 時分 */
    public static final String TIME_HH_MM = "HH:mm";
    /** Constant HHmm 時分 None delimiter */
    public static final String TIME_HHMM = "HHmm";
    /** Constant mm:ss 分秒 */
    public static final String TIME_MM_SS = "mm:ss";
    /** Constant mmss 分秒 None delimiter */
    public static final String TIME_MMSS = "mmss";

    private static final String DEFAULT_DATE_TIME_PATTERN = YYYY_MM_DD_HH_MM_SS_DASH;
    private static final String DEFAULT_DATE_PATTERN = YYYYMMDD;

    // SimpleDateFormat函式語法:
    //
    // G 年代標誌符
    // y 年
    // M 月
    // d 日
    // h 時 在上午或下午 (1~12)
    // H 時 在一天中 (0~23)
    // m 分
    // s 秒
    // S 毫秒
    // E 星期
    // D 一年中的第幾天
    // F 一月中第幾個星期幾
    // w 一年中第幾個星期
    // W 一月中第幾個星期
    // a 上午 / 下午 標記符
    // k 時 在一天中 (1~24)
    // K 時 在上午或下午 (0~11)
    // z 時區
    //
    // example:
    // SimpleDateFormat myFmt=new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒");
    // SimpleDateFormat myFmt=new SimpleDateFormat("yy/MM/dd HH:mm");

    // 等價於now.toLocaleString()
    // SimpleDateFormat myFmt=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // SimpleDateFormat myFmt=new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒 E ");
    // SimpleDateFormat myFmt=new SimpleDateFormat(
    // "一年中的第 D 天 一年中第w個星期 一月中第W個星期 在一天中k時 z時區");

    // =======取得目前日期時間=======
    /**
     * 取得目前日期時間 (system 格式)
     *
     * @return Date() 目前日期時間
     */
    public static Date dateTimeNow() {
        return new Date();
    }

    /**
     * 取得目前日期時間 String (Default 格式)
     *
     * @return String
     */
    public static String dateTimeNowString() {

        return dateTimeToString(dateTimeNow(), "");
    }

    /**
     * 取得目前日期時間 String (指定 格式)
     *
     * @return String
     * @param datePattern a  String  object
     */
    public static String dateTimeNowString(String datePattern) {

        return dateTimeToString(dateTimeNow(), datePattern);
    }

    /**
     * 目前日期 String (defaultDatePattern)
     *
     * @return Date 傳回格式化之後的日期字串
     */
    public static String dateNowString() {
        return dateTimeNowString(DEFAULT_DATE_PATTERN);
    }

    /**
     * 目前日期 String (指定 DatePattern)
     *
     * @param datePattern 格式
     * @return Date 傳回格式化之後的日期字串
     */
    public static String dateNowString(String datePattern) {
        return dateTimeNowString(datePattern);
    }

    // =======日期格式轉換=======

    /**
     * 取得日期時間 String (指定日期與格式)
     *
     * @param date        日期
     * @param datePattern 格式
     * @return String
     */
    public static String dateTimeToString(Date date, String datePattern) {
        if (StringUtils.isBlank(datePattern)) {
            datePattern = DEFAULT_DATE_TIME_PATTERN;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
        return dateFormat.format(date);
    }

    /**
     * 格式化日期物件為日期
     *
     * @param date        日期
     * @param datePattern 格式
     * @return Date 傳回格式化之後的日期字串
     */
    public static Date objectDateToDate(Object date, String datePattern) {
        if (StringUtils.isBlank(datePattern)) {
            datePattern = DEFAULT_DATE_TIME_PATTERN;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
        String dateString = dateFormat.format(date);
        return stringToDate(dateString, datePattern);
    }

    /**
     * 格式化日期物件為日期
     *
     * @param date 日期
     * @return Date 傳回格式化之後的日期字串
     */
    public static Date objectDateToDate(Object date) {
        return objectDateToDate(date, DEFAULT_DATE_TIME_PATTERN);
    }

    /**
     * 格式化日期字串為日期
     *
     * @param datePattern 格式
     * @return Date 傳回格式化之後的日期字串
     * @param inDate a  String  object
     */
    public static Date stringToDate(String inDate, String datePattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
        try {
            return dateFormat.parse(inDate);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 取得 Sting Date 日期格式
     *
     * @return Date 日期格式 yyyy-MM-dd HH:mm:ss
     * @param inDate a  String  object
     */
    public static Date stringToDate(String inDate) {
        return stringToDate(inDate, DEFAULT_DATE_TIME_PATTERN);
    }

    // =======日期檢核=======
    /**
     * 檢核 Sting Date 是否非合法
     *
     * @return Boolean true: 非合法
     * @param inDate      a  String  object
     * @param datePattern a  String  object
     */
    public static boolean isNotValidDate(String inDate, String datePattern) {
        return !isValidDate(inDate, datePattern);
    }

    /**
     * 檢核 Sting Date 是否合法
     *
     * @return Boolean true:合法
     * @param inDate      a  String  object
     * @param datePattern a  String  object
     */
    public static boolean isValidDate(String inDate, String datePattern) {

        /* Check if date is 'null' */
        if (StringUtils.isBlank(inDate.trim())) {
            return false;
        }
        /* Date is not 'null' */
        else {
            /*
             * Set preferred date format, For example MM-dd-yyyy, MM.dd.yyyy,dd.MM.yyyy etc.
             */
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
            simpleDateFormat.setLenient(false);
            /*
             * Create Date object parse the string into date
             */
            try {
                simpleDateFormat.parse(inDate);
                return true;
            }
            /* Date format is invalid */
            catch (Exception eX) {
                return false;
            }
            /* Return false by Default */

        }
    }

    // =======民國年與西元年轉換=======
    /**
     * Transfer AD date to minguo date. 西元年 yyyyMMdd 轉 民國年 yyyMMdd
     *
     * @param date 西元年月日
     * @return Date 民國年月日
     */
    public static String transferADDateToMinguoDate(Date date) {
        String dateString = dateTimeToString(date, YYYYMMDD);
        LocalDate localDate = LocalDate.parse(dateString, DateTimeFormatter.ofPattern(YYYYMMDD));
        return MinguoDate.from(localDate).format(DateTimeFormatter.ofPattern("yyyMMdd"));
    }

    /**
     * Transfer minguo date to AD date. 民國年 yyyMMdd 轉 西元年 YYYYMMDD
     *
     * @return Date 西元年
     * @param minguoDateString a  String  object
     */
    public static String transferMinguoDateToADDate(String minguoDateString) {

        Chronology chronology = MinguoChronology.INSTANCE;
        DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder().parseLenient().appendPattern("yyyMMdd")
                .toFormatter().withChronology(chronology).withDecimalStyle(DecimalStyle.of(Locale.getDefault()));

        ChronoLocalDate chronoLocalDate = chronology.date(dateTimeFormatter.parse(minguoDateString));
        return LocalDate.from(chronoLocalDate).format(DateTimeFormatter.ofPattern(YYYYMMDD));
    }

    // =======日期計算=======
    /**
     * 計算天數 Days between two date (dateDate)
     *
     * @param startDate 開始日期字串
     * @param endDate   結束日期字串
     * @return long 計算後天數
     */
    public static long daysBetweenDate(Date startDate, Date endDate) {
        long betweenDays = endDate.getTime() - startDate.getTime();
        return betweenDays / 1000 / 60 / 60 / 24;
    }

    /**
     * 計算月數 Months between two date (dateDate)
     *
     * @param startDate 開始日期字串
     * @param endDate   結束日期字串
     * @return long 計算後月數
     */
    public static long monthsBetweenDate(Date startDate, Date endDate) {
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(endDate);
        int yearDiff = endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR);
        int monthDiff = endCal.get(Calendar.MONTH) - startCal.get(Calendar.MONTH);
        return (long) yearDiff * 12 + monthDiff;
    }

    /**
     * 計算年數 Years between two date (dateDate)
     *
     * @param startDate 開始日期字串
     * @param endDate   結束日期字串
     * @return long 計算後年數
     */
    public static long yearsBetweenDate(Date startDate, Date endDate) {
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(endDate);
        return (long) endCal.get(Calendar.YEAR) - startCal.get(Calendar.YEAR);
    }

    /**
     * 日期加指定的天數
     *
     * @param date   基準日期
     * @param offset 加減數量 分鐘 / 小時 / 日 / 月 / 年
     * @return Date 加減後的日期
     * @param offsetType (Calendar.MINUTE / Calendar.HOUR / Calendar.DATE /
     *                   Calendar.MONTH / Calendar.YEAR)
     */
    public static Date getOffsetDate(Date date, int offset, int offsetType) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(offsetType, offset);
        return calendar.getTime();
    }

    /**
     * Julian Date of year (一年中的第幾天 例如 2/5 = 36 , 12/31 = 365 or 366)
     *
     * @param inDate 日期 yyyy/MM/dd
     * @return String 格式輸出字串
     */
    public static String julianDate(Date inDate) {

        String rtnDate = "000";
        try {
            rtnDate = new SimpleDateFormat("D").format(inDate);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return rtnDate;
    }
}

單元測試程式碼 DateUtilsTest.java

package tw.lewishome.webapp.base.utility.common;

import org.junit.jupiter.api.Test;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import static org.junit.jupiter.api.Assertions.*;

public class DateUtilTest {

    @Test
    void testDateTimeNow() {
        Date now = DateUtils.dateTimeNow();
        assertNotNull(now);
        // Should be within a few seconds of system time
        long diff = Math.abs(now.getTime() - System.currentTimeMillis());
        assertTrue(diff < 2000);
    }

    @Test
    void testDateTimeNowStringDefault() {
        String nowStr = DateUtils.dateTimeNowString();
        assertNotNull(nowStr);
        assertEquals(19, nowStr.length()); // "yyyy-MM-dd HH:mm:ss"
    }

    @Test
    void testDateTimeNowStringWithPattern() {
        String datePatten = DateUtils.YYYYMMDDHHMMSS;
        String nowStr = DateUtils.dateTimeNowString(datePatten);
        assertNotNull(nowStr);
        assertEquals(14, nowStr.length());
    }

    /**
     * @throws Exception
     */
    @Test
    void testDateTimeToString() throws Exception {
        Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-01");
        String str = DateUtils.dateTimeToString(date, "yyyy/MM/dd");
        assertEquals("2024/06/01", str);
    }

    @Test
    void testDateNowStringDefault() {
        String nowStr = DateUtils.dateNowString();
        assertNotNull(nowStr);
        assertEquals(8, nowStr.length()); // "yyyyMMdd"
    }

    @Test
    void testDateNowStringWithPattern() {
        String nowStr = DateUtils.dateNowString("yyyy-MM-dd");
        assertNotNull(nowStr);
        assertEquals(10, nowStr.length());
    }

    /**
     * @throws Exception
     */
    @Test
    void testObjectDateToDateWithPattern() throws Exception {
        Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-01");
        Date result = DateUtils.objectDateToDate(date, "yyyy-MM-dd");
        assertEquals(date, result);
    }

    /**
     * @throws Exception
     */
    @Test
    void testObjectDateToDateDefault() throws Exception {
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2024-06-01 12:34:56");
        Date result = DateUtils.objectDateToDate(date);
        assertEquals(date, result);
    }

    @Test
    void testStringToDateWithPattern() {
        Date date = DateUtils.stringToDate("2024-06-01", "yyyy-MM-dd");
        assertNotNull(date);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        assertEquals("2024-06-01", sdf.format(date));
    }

    @Test
    void testStringToDateDefault() {
        String dateStr = "2024-06-01 12:34:56";
        Date date = DateUtils.stringToDate(dateStr);
        assertNotNull(date);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        assertEquals(dateStr, sdf.format(date));
    }

    @Test
    void testIsVaildDateValid() {
        assertTrue(DateUtils.isValidDate("2024-06-01", "yyyy-MM-dd"));
    }

    @Test
    void testIsVaildDateInvalid() {
        assertFalse(DateUtils.isValidDate("2024-13-01", "yyyy-MM-dd"));
        assertFalse(DateUtils.isValidDate("", "yyyy-MM-dd"));
        assertFalse(DateUtils.isValidDate("notadate", "yyyy-MM-dd"));
    }

    /**
     * @throws Exception
     */
    @Test
    void testJulianDate() throws Exception {
        Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2024-02-05");
        String julian = DateUtils.julianDate(date);
        assertEquals("36", julian); // 2024 is a leap year, Feb 5 is the 36th day
    }

    /**
     * @throws Exception
     */
    @Test
    void testGetOffsetDate() throws Exception {
        Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-01");
        Date nextDay = DateUtils.getOffsetDate(date, 1, Calendar.DATE);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        assertEquals("2024-06-02", sdf.format(nextDay));
    }

    /**
     * @throws Exception
     */
    @Test
    void testTransferADDateToMinguoDate() throws Exception {
        Date adDate = new SimpleDateFormat("yyyyMMdd").parse("20240601");
        String minguoDate = DateUtils.transferADDateToMinguoDate(adDate);
        // 2024-06-01 AD = 民國113年06月01日, so yyyMMdd = 1130601
        assertEquals("1130601", minguoDate);
    }

    /**
     * @throws Exception
     */
    @Test
    void testTransferMinguoDateToADDate() throws Exception {
        String minguoDate = "1130601";
        String adDate = DateUtils.transferMinguoDateToADDate(minguoDate);

        // 民國113年06月01日 = 2024-06-01 AD
        assertEquals("20240601", adDate);
    }

    /**
     * @throws Exception
     */
    @Test
    void testDaysBetweendateDate() throws Exception {
        Date start = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-01");
        Date end = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-10");
        long days = DateUtils.daysBetweenDate(start, end);
        assertEquals(9, days);
    }

    /**
     * @throws Exception
     */
    @Test
    void testDaysBetweendateDateNegative() throws Exception {
        Date start = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-10");
        Date end = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-01");
        long days = DateUtils.daysBetweenDate(start, end);
        assertEquals(-9, days);
    }

    /**
     * @throws Exception
     */
    @Test
    void testMonthsBetweendateDateNegative() throws Exception {
        Date start = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-10");
        Date end = new SimpleDateFormat("yyyy-MM-dd").parse("2023-06-01");
        long months = DateUtils.monthsBetweenDate(start, end);
        assertEquals(-12, months);
    }

    @Test
    void testYearsBetweendateDateNegative() throws Exception {
        Date start = new SimpleDateFormat("yyyy-MM-dd").parse("2024-06-10");
        Date end = new SimpleDateFormat("yyyy-MM-dd").parse("2020-06-01");
        long years = DateUtils.yearsBetweenDate(start, end);
        assertEquals(-4, years);
    }

}

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言