Java Joda-Time 處理時間工具類(JDK1.7以上)


1. 環境准備:

① JDK 1.7以上

② Maven工程(引入Maven工程包)

③ 開發工具(IDEA/Eclipse)

2. 代碼示例:

import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.util.*;

/**
 * 基於JDK13,聯合Joda-Time類的時間工具類<br/>
 * Joda 是一種令人驚奇的高效工具。無論您是計算日期、打印日期,或是解析日期,Joda都將是工具箱中的便捷工具<br/>
 * 1.引入joda-time的jar包
 * 2.官方學習網址:https://www.joda.org/joda-time/
 * 3.Maven引入示例如下:
 * <pre>
 *   ========================
 *   <dependency>
 *     <groupId>joda-time</groupId>
 *     <artifactId>joda-time</artifactId>
 *     <version>2.10.5</version>
 *   </dependency>
 *   ========================
 * <pre/>
 *
 * @author Administrator
 */
public class DateUtil {

    public static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";
    public static final String YMDHMS_CN = "yyyy年MM月dd日 HH時:mm分:ss秒";
    public static final String YMD = "yyyy-MM-dd";
    public static final String YMD_CN = "yyyy年MM月dd日";
    public static final String HMS = "HH:mm:ss";
    public static final String HMS_CN = "HH時mm分ss秒";
    public static final String MdyhmsSA = "MM/dd/yyyy hh:mm:ss.SSSa"; // 09/06/2009 02:30:00.000PM
    public static final String dMyHms = "dd-MM-yyyy HH:mm:ss"; // 06-Sep-2009 14:30:00
    public static final String EdMyHmsA = "EEEE dd MMMM, yyyy HH:mm:ssa";// Sunday 06 September, 2009 14:30:00PM
    public static final String MdyHmZZ = "MM/dd/yyyy HH:mm ZZZZ"; // 09/06/2009 14:30 America/Chicago
    public static final String MdyHmZ = "MM/dd/yyyy HH:mm Z"; // 09/06/2009 14:30 -0500

    public static final String DAY = "day", WEEK = "week", MONTH = "month", YEAR = "year";
    public static final String HOUR = "hour", MINUTE = "minute", SECOND = "second";

    /**
     * 日期 → 字符
     *
     * @param date    日期
     * @param pattern 格式(例如 ”yyyy-MM-dd HH:mm:ss“)
     * @return 數據的格式為:yyyy-MM-dd HH:mm:ss
     */
    public static String getDateTimeStr(Date date, String pattern) {
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(pattern);
    }

    public static String getDateTimeStrLocale(Date date, String pattern) {
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(pattern, Locale.CHINA);
    }

    public static Date getDateTime(String dateTimeStr, String pattern) {
        DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
        DateTime dateTime = new DateTime(dateTimeStr).toDateTime();
        return dateTime.toDate();
    }

    /**
     * 時間加減運算
     *
     * @param datetime joda-time時間類
     * @param period   周期(年月日時分秒周)
     * @param count    偏移量
     * @return 時間字符串(格式:yyyy-MM-dd HH:mm:ss)
     */
    public static String getDateTime(DateTime datetime, String period, int count) {
        DateTime result = new DateTime();
        switch (period) {
            case DAY:
                result = datetime.plusDays(count);
                break;
            case MONTH:
                result = datetime.plusMonths(count);
                break;
            case YEAR:
                result = datetime.plusYears(count);
                break;
            case WEEK:
                result = datetime.plusWeeks(count);
                break;
            case HOUR:
                result = datetime.plusHours(count);
                break;
            case MINUTE:
                result = datetime.plusMinutes(count);
                break;
            case SECOND:
                result = datetime.plusSeconds(count);
                break;
            default:
                break;
        }
        return result.toString(YMDHMS, Locale.CHINA);
    }


    /**
     * 重置當前時間(如果有非法值輸入則自動默認為日期元素的起始值)
     *
     * @param year   年份(1900~9999)
     * @param month  月份(1~12)
     * @param day    日(如果是2月,平年最大為28日,閏年最大為29日)
     * @param hour   小時(0~23)
     * @param minute 分鍾(0~59)
     * @param second 秒鍾(0~59)
     * @return
     */
    public static DateTime setCurrDateTime(int year, int month, int day, int hour, int minute, int second) {
        year = String.valueOf(year).length() <= 9999 && String.valueOf(year).length() >= 1900 ? year :
                new DateTime().getYear();
        month = month >= 1 && month <= 12 ? month : 1;
        List<Integer> monthHas31 = Arrays.asList(1, 3, 5, 7, 8, 10, 12);
        if (month == 2) {
            // flag(true:平年,false:閏年)
            boolean flag = (year % 4 != 0 || year % 100 == 0 && year % 400 != 0);
            day = day >= 1 && day <= (flag ? 28 : 29) ? day : 1;
        } else {
            day = day >= 1 && day <= (monthHas31.contains(month) ? 31 : 30) ? day : 1;
        }
        hour = (hour >= 0 && hour <= 23) ? hour : 0;
        minute = (minute >= 0 && minute <= 59) ? minute : 0;
        second = (second >= 0 && second <= 59) ? second : 0;
        DateTime dateTime = DateTime.now().withYear(year).withMonthOfYear(month).withDayOfMonth(day)
                .withHourOfDay(hour).withMinuteOfHour(minute).withSecondOfMinute(second);
        return dateTime;
    }

    /**
     * d1 是否在 d2 之前? true 是的,false 不是
     *
     * @param d1 第一個時間
     * @param d2 第二個時間
     * @return true/false
     */
    public static boolean compare(DateTime d1, DateTime d2) {
        if (d1.isBefore(d2)) {
            return true;
        }
        return false;
    }

    /**
     * 根據周期計算兩個時間的偏移量
     *
     * @param d1     第一個時間
     * @param d2     第二個時間
     * @param period 周期(年月日時分秒周)
     * @return
     */
    public static int calRange(DateTime d1, DateTime d2, String period) {
        int result = 0;
        if (DAY.equals(period)) {
            result = Days.daysBetween(d1, d2).getDays();
        } else if (MONTH.equals(period)) {
            result = Months.monthsBetween(d1, d2).getMonths();
        } else if (YEAR.equals(period)) {
            result = Years.yearsBetween(d1, d2).getYears();
        } else if (HOUR.equals(period)) {
            result = Hours.hoursBetween(d1, d2).getHours();
        } else if (MINUTE.equals(period)) {
            result = Minutes.minutesBetween(d1, d2).getMinutes();
        } else if (SECOND.equals(period)) {
            result = Seconds.secondsBetween(d1, d2).getSeconds();
        } else if (WEEK.equals(period)) {
            result = Weeks.weeksBetween(d1, d2).getWeeks();
        } else {
            return result;
        }
        return Math.abs(result);
    }

    /**
     * 獲取指定日期的所在周期的最后日期或第一個日期(返回格式:yyyy-MM-dd HH:mm:ss)<br/>
     * 例如: 指定日期為:”2020-02-20“,周期為:”day“, isMax為true; 返回結果為:”2020-02-29“
     *
     * @param dateTime joda-time 指定日期
     * @param period   周期(年月日時周)
     * @param isMax    true:最大日期,false:最小日期
     * @return
     */
    public static DateTime getStartOrEnd(DateTime dateTime, String period, boolean isMax) {
        DateTime d = new DateTime();
        if (YEAR.equals(period)) {
            d = isMax ? dateTime.dayOfYear().withMaximumValue() : dateTime.dayOfYear().withMinimumValue();
        } else if (MONTH.equals(period)) {
            d = isMax ? dateTime.dayOfMonth().withMaximumValue() : dateTime.dayOfMonth().withMinimumValue();
        } else if (WEEK.equals(period)) {
            d = isMax ? dateTime.dayOfWeek().withMaximumValue() : dateTime.dayOfWeek().withMinimumValue();
        } else if (HOUR.equals(period)) {
            d = isMax ? dateTime.hourOfDay().withMaximumValue() : dateTime.hourOfDay().withMinimumValue();
        }
        d = isMax ? d.withHourOfDay(23).withMinuteOfHour(59).withSecondOfMinute(59)
                : d.withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0);
        return d;
    }

    /**
     * 獲取指定日期的所在周期的起止時間
     *
     * @param dateTime 日期(Joda-Time)
     * @param period   周期(年月周)
     * @return ”yyyy-MM-dd,yyyy-MM-dd“
     */
    public static String getStartAndEndByPeriod(DateTime dateTime, String period) {
        DateTime d = new DateTime();
        String start = "", end = "";
        if (YEAR.equals(period)) {
            start = dateTime.dayOfYear().withMinimumValue().toString(YMD);
            end = dateTime.dayOfYear().withMaximumValue().toString(YMD);
        } else if (MONTH.equals(period)) {
            start = dateTime.dayOfMonth().withMinimumValue().toString(YMD);
            end = dateTime.dayOfMonth().withMaximumValue().toString(YMD);
        } else if (WEEK.equals(period)) {
            start = dateTime.dayOfWeek().withMinimumValue().toString(YMD);
            end = dateTime.dayOfWeek().withMaximumValue().toString(YMD);
        } else {
            // TODO 季度
        }
        return start.concat(",").concat(end);
    }

    /***
     * String → Date(JDK)
     *
     * @param dateTimeStr 需要轉化的string類型的字符串
     * @param pattern 轉化規則
     * @return 返回轉化后的Date類型的時間
     */
    public static Date strToDate(String dateTimeStr, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(pattern);
        DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
        return dateTime.toDate();
    }

    /**
     * String → DateTime(JodaTime)
     *
     * @param dateTimeStr 日期字符串(格式最低要求:yyyy-MM-dd)
     * @param pattern     轉化規則
     * @return
     */
    public static DateTime strToDateTime(String dateTimeStr, String pattern) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(pattern);
        DateTime dateTime = dateTimeFormatter.parseDateTime(dateTimeStr);
        return dateTime;
    }

    /**
     * 計算:兩個時間相距天數
     *
     * @param d1 時間1 DateTime:joda-time
     * @param d2 時間2 DateTime:joda-time
     * @return 偏移數
     */
    public static int getDays(DateTime d1, DateTime d2) {
        Period p = new Period(d1, d2, PeriodType.days());
        return Math.abs(p.getDays());
    }

    /**
     * 計算兩時間相隔多少周期
     *
     * @param dateTimeStr1 (格式為: yyyy-MM-dd HH:mm:ss)
     * @param dateTimeStr2 (格式為: yyyy-MM-dd HH:mm:ss)
     * @param pattern      轉化規則
     * @param period       周期(年月日周時分秒: year,month,day,week,hour,minute,second)
     * @return
     */
    public static int getPeriods(String dateTimeStr1, String dateTimeStr2, String pattern, String period) {
        int num = 0;
        if (dateTimeStr1 == null || dateTimeStr1.isBlank() || dateTimeStr2 == null || dateTimeStr2.isBlank()) {
            return num;
        }
        DateTime d1 = DateTimeFormat.forPattern(pattern).parseDateTime(dateTimeStr1);
        DateTime d2 = DateTimeFormat.forPattern(pattern).parseDateTime(dateTimeStr2);
        // 默認 計算相隔天數
        PeriodType periodType = PeriodType.days();
        if (DAY.equals(period)) {
            num = new Period(d1, d2, periodType).getDays();
        } else if (MONTH.equals(period)) {
            periodType = PeriodType.months();
            num = new Period(d1, d2, periodType).getMonths();
        } else if (WEEK.equals(period)) {
            periodType = PeriodType.weeks();
            num = new Period(d1, d2, periodType).getWeeks();
        } else if (YEAR.equals(period)) {
            periodType = PeriodType.years();
            num = new Period(d1, d2, periodType).getYears();
        } else if (HOUR.equals(period)) {
            periodType = PeriodType.hours();
            num = new Period(d1, d2, periodType).getHours();
        } else if (MINUTE.equals(period)) {
            periodType = PeriodType.minutes();
            num = new Period(d1, d2, periodType).getMinutes();
        } else if (SECOND.equals(period)) {
            periodType = PeriodType.seconds();
            num = new Period(d1, d2, periodType).getSeconds();
        }
        return Math.abs(num);
    }

    /**
     * 判斷時間是否在指定區間內
     *
     * @param start       開始時間
     * @param end         結束時間
     * @param aimDateTime 被判斷的時間
     * @return true:是,false:否
     */
    public static boolean isExist(DateTime start, DateTime end, String aimDateTime) {
        Interval interval = new Interval(start, end);
        boolean flag = interval.contains(new DateTime(strToDateTime(aimDateTime, YMDHMS)));
        return flag;
    }

    /**
     * 判斷指定日期是否在當前時間之后
     */
    public static boolean isAfterNow(DateTime dateTime) {
        return dateTime.isAfterNow();
    }

    /**
     * 判斷指定日期是否在當前時間之前
     */
    public static boolean isBeforeNow(DateTime dateTime) {
        return dateTime.isBeforeNow();
    }

    /**
     * 得到指定日期為星期幾
     *
     * @param dateTime 指定日期(Joda-time)
     * @return 中文星期幾
     */
    public static String getWeekDay(DateTime dateTime) {
        String result = null;
        if (DateTimeConstants.SUNDAY == dateTime.getDayOfWeek()) {
            result = "星期日";
        } else if (DateTimeConstants.SATURDAY == dateTime.getDayOfWeek()) {
            result = "星期六";
        } else if (DateTimeConstants.FRIDAY == dateTime.getDayOfWeek()) {
            result = "星期五";
        } else if (DateTimeConstants.THURSDAY == dateTime.getDayOfWeek()) {
            result = "星期四";
        } else if (DateTimeConstants.WEDNESDAY == dateTime.getDayOfWeek()) {
            result = "星期三";
        } else if (DateTimeConstants.TUESDAY == dateTime.getDayOfWeek()) {
            result = "星期二";
        } else if (DateTimeConstants.MONDAY == dateTime.getDayOfWeek()) {
            result = "星期一";
        }
        return result;
    }

    /**
     * JDK實現:判斷指定日期所在的季度<br/>
     * <pre>
     * 1 第一季度 (一月,二月,三月)
     * 2 第二季度 (四月,五月,六月)
     * 3 第三季度 (七月,八月,九月)
     * 4 第四季度 (十月,十一月,十二月)
     * <pre/>
     * @param date 指定JDK的日期
     * @return 1:第一季度,2:第二季度,3:第三季度,4:第四季度 (如果返回0,請檢查輸入參數)
     */
    public static int getSeason(Date date) {
        if (date == null) {
            return 0;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH), season = 0;
        if (month == Calendar.JANUARY || month == Calendar.FEBRUARY || month == Calendar.MARCH) {
            season = 1;
        } else if (month == Calendar.APRIL || month == Calendar.MAY || month == Calendar.JUNE) {
            season = 2;
        } else if (month == Calendar.JULY || month == Calendar.AUGUST || month == Calendar.SEPTEMBER) {
            season = 3;
        } else if (month == Calendar.OCTOBER || month == Calendar.NOVEMBER || month == Calendar.DECEMBER) {
            season = 4;
        }
        return season;
    }

    /**
     * 取得季度月
     *
     * @param date 指定日期
     * @return 日期數組
     */
    public static Date[] getSeasonDate(Date date) {
        Date[] season = new Date[3];
        if (date == null) {
            return season;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int nSeason = getSeason(date);
        if (nSeason == 1) {
            // 第一季度
            c.set(Calendar.MONTH, Calendar.JANUARY);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.FEBRUARY);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.MARCH);
            season[2] = c.getTime();
        } else if (nSeason == 2) {
            // 第二季度
            c.set(Calendar.MONTH, Calendar.APRIL);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.MAY);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.JUNE);
            season[2] = c.getTime();
        } else if (nSeason == 3) {
            // 第三季度
            c.set(Calendar.MONTH, Calendar.JULY);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.AUGUST);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.SEPTEMBER);
            season[2] = c.getTime();
        } else if (nSeason == 4) {
            // 第四季度
            c.set(Calendar.MONTH, Calendar.OCTOBER);
            season[0] = c.getTime();
            c.set(Calendar.MONTH, Calendar.NOVEMBER);
            season[1] = c.getTime();
            c.set(Calendar.MONTH, Calendar.DECEMBER);
            season[2] = c.getTime();
        }
        return season;
    }

    /**
     * 計算當指定日期距離所在日期的第幾天<br/>
     * 例如:當前日期為 2020-04-01,四月一日是第二季度的一天,傳入的日期為2020-04-02;則輸出的結果為:1 (即:已經相隔一天了)
     *
     * @param datetime 指定日期
     * @return num==0 可能1.傳入參數為null,2.傳入的日期為當前季度所在的第一天
     */
    public static int calDuringSeasonDays(DateTime datetime) {
        if (datetime == null) {
            return 0;
        }
        int month = datetime.getMonthOfYear();
        DateTime startTime = null;
        if (month == 1 || month == 2 || month == 3) {
            startTime = datetime.withMonthOfYear(1).dayOfMonth().withMinimumValue();
        } else if (month == 4 || month == 5 || month == 6) {
            startTime = datetime.withMonthOfYear(4).dayOfMonth().withMinimumValue();
        } else if (month == 7 || month == 8 || month == 9) {
            startTime = datetime.withMonthOfYear(7).dayOfMonth().withMinimumValue();
        } else if (month == 10 || month == 11 || month == 12) {
            startTime = datetime.withMonthOfYear(10).dayOfMonth().withMinimumValue();
        }
        return Math.abs(Days.daysBetween(startTime, datetime).getDays());
    }

    public static void main(String[] args) {
        // JDK 得到當前時間
        Date date = new Date();
        // JodaTime 得到當前時間
        Date dateNow = DateTime.now().toDate();
        // 創建日期的方式一:(以此為:年月日時分秒毫秒)
        DateTime dateTime = new DateTime(2020, 4, 2, 0, 0, 0, 0);
        String dateTimeStr = "2021-01-02 20:20:20", dateTimeStr2 = "2020-02-12 23:20:20";
        DateTime nextFirstDay = new DateTime().dayOfYear().withMinimumValue();
        DateTime nextLastDay = new DateTime().dayOfYear().withMaximumValue();
        System.out.println(calDuringSeasonDays(dateTime));
//        System.out.println(Arrays.asList(getSeasonDate(dateNow)));
//        System.out.printf("當前日期所在的季度為:%s\n", getSeason(new Date()));
//        System.out.printf("JDK獲取當前日期時間戳推薦System.currentTimeMillis:%s\n", System.currentTimeMillis());
//        System.out.println("jodaTime得到當前時間戳(建議):" + DateTimeUtils.currentTimeMillis());
//        System.out.println("JDK得到當前時間戳1(建議):" + System.currentTimeMillis());
//        System.out.println("JDK得到當前時間戳2:" + "new Date().getTime() 這種方式已經不推薦使用!");
//        System.out.println(getWeekDay(DateTime.now()));
//        System.out.println(getStartAndEndByPeriod(new DateTime(date), YEAR));
//        System.out.println(dateTime.toString());
//        System.out.println(isExist(nextFirstDay, nextLastDay, dateTimeStr));
//        System.out.println(getPeriods(dateTimeStr, dateTimeStr2, YMDHMS, MINUTE));
//        System.out.println(strToDate(dateTimeStr, YMDHMS));
//        System.out.println(strToDateTime(dateTimeStr, YMDHMS));
//        System.out.println(getDays(nextLastDay, nextFirstDay));
//        System.out.println(getStartOrEnd(new DateTime(date), YEAR, true).toString(YMDHMS));
//        System.out.println(calRange(nextLastDay, nextFirstDay, SECOND));
//        System.out.println(setCurrDateTime(220, 21, 33, 23, 59, 59).toString(YMDHMS));
//        System.out.println(new DateTime().getYear());
//        System.out.println(DateTime.now().toString(YMDHMS, Locale.CHINA));
//        System.out.println(getDateTime(new DateTime(date), DAY, -3));
//        System.out.println(getDateTime(dateTimeStr, YMDHMS));
//        System.out.println(getDateTimeStr(date, YMDHMS_CN));
//        System.out.println(getDateTimeStrLocale(date, YMD_CN));
//        System.out.println(new DateTime(date)); // 輸出:2020-04-04T21:33:11.625+08:00
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM