Java 第三方日期工具类 JodaTime 使用示例

552 阅读5分钟

一、认识Joda Time 日期工具类

功能特色: A selection of key features:

  • LocalDate - date without time
  • LocalTime - time without date
  • Instant - an instantaneous point on the time-line
  • DateTime - full date and time with time-zone
  • DateTimeZone - a better time-zone
  • Duration and Period - amounts of time
  • Interval - the time between two instants
  • A comprehensive and flexible formatter-parser 来源: www.joda.org/joda-time/

二、引入依赖

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.10.10</version>
</dependency>

三、完整源码

核心功能:

  • LocalDate 和 Date 互转;
  • 返回未来指定N个(年月日时分秒周)的日期;
  • 字符串转 LocalDate / LocalDateTime;
  • …………TODO 更多功能等待继续扩展;
import org.joda.time.*;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.FormatUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * Joda time 日期工具类
 *
 * @author drew
 * @create 2021-06-27 16:36
 */
public class JodaTimeUtils {
    /**
     * 日期时间
     */
    private static final String yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
    /**
     * 年月日
     */
    private static final String yyyyMMdd = "yyyy-MM-dd";
    /**
     * 时分秒
     */
    private static final String HHMMSS = "HH:mm:ss";
    /**
     * 秒
     */
    private static final String DATE_TYPE_SECONDS = "seconds";
    /**
     * 分
     */
    private static final String DATE_TYPE_MINUTE = "minute";
    /**
     * 时
     */
    private static final String DATE_TYPE_HOUR = "hour";
    /**
     * 日
     */
    private static final String DATE_TYPE_DAY = "day";
    /**
     * 周
     */
    private static final String DATE_TYPE_WEEK = "week";
    /**
     * 月
     */
    private static final String DATE_TYPE_MONTH = "month";
    /**
     * 年
     */
    private static final String DATE_TYPE_YEAR = "year";

    /**
     * 获取指定日期的当前月份(例如 输入 new LocalDate() 返回当前日期的英文月份)
     *
     * @param dateOfBirth 出生日期(或指定日期)
     * @return 月份
     */
    public static String getBirthMonthTextEn(LocalDate dateOfBirth) {
        return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH);
    }

    /**
     * 返回中文月份(例如 new LocalDate() 返回 六月)
     *
     * @param date
     * @return
     */
    public static String getBirthMonthTextCn(LocalDate date) {
        // 或 return date.monthOfYear().getAsText(Locale.CHINESE);
        return date.monthOfYear().getAsText(Locale.CHINA);
    }

    /**
     * 获取指定日期的月份数字
     *
     * @param date 日期格式:yyyy-MM-dd
     * @return 1 - 12
     */
    public static int getBirthMonthNumber(LocalDate date) {
        return date.getMonthOfYear();
    }

    /**
     * java.util.Date 转 org.joda.LocalDate
     *
     * @param date 日期
     * @return org.joda.LocalDate
     */
    public static LocalDate toLocalDate(Date date) {
        return new LocalDate(LocalDate.fromDateFields(date));
    }

    /**
     * 日期时间字符串转 org.joda.LocalDate
     *
     * @param dateStr 日期字符串(例如:“yyyy-MM-dd”)
     * @return org.joda.LocalDate
     */
    public static LocalDate toLocalDate(String dateStr) {
        return new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
    }

    /**
     * java.util.Date 转 org.joda.LocalDateTime
     *
     * @param date 日期
     * @return org.joda.LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return new LocalDateTime(LocalDateTime.fromDateFields(date));
    }

    /**
     * 日期时间字符串转 org.joda.LocalDate
     *
     * @param dateStr 日期字符串(例如:“yyyy-MM-dd”)
     * @return org.joda.LocalDate
     */
    public static LocalDateTime toLocalDateTime(String dateStr) {
        return new LocalDateTime(LocalDateTime.parse(dateStr, DateTimeFormat.forPattern(yyyyMMddHHmmss)));
    }

    @Deprecated
    public static boolean isLeap(LocalDate localDate, String dateType) {
        if (dateType.equals(DATE_TYPE_DAY)) {
            return localDate.dayOfYear().isLeap();
        }
        if (dateType.equals(DATE_TYPE_YEAR)) {
            return localDate.year().isLeap();
        }
//        localDate.centuryOfEra().isLeap();
//        localDate.era().isLeap();
//        localDate.weekOfWeekyear().isLeap();
//        localDate.monthOfYear().isLeap();
//        localDate.dayOfWeek().isLeap();
//        localDate.dayOfMonth().isLeap();
//        localDate.weekyear().isLeap();
        return false;
    }

    /**
     * 获取指定的未来时间点
     *
     * @param localDateTime org.joda.time.LocalDateTime
     * @param dateType      日期类型(年月日时分秒周)
     * @param number        跨度
     * @return org.joda.LocalDateTime
     */
    public static LocalDateTime plus(LocalDateTime localDateTime, String dateType, int number) {
        if (dateType.equals(DATE_TYPE_YEAR)) {
            return localDateTime.plusYears(number);
        }
        if (dateType.equals(DATE_TYPE_MONTH)) {
            return localDateTime.plusMonths(number);
        }
        if (dateType.equals(DATE_TYPE_WEEK)) {
            return localDateTime.plusWeeks(number);
        }
        if (dateType.equals(DATE_TYPE_DAY)) {
            return localDateTime.plusDays(number);
        }
        if (dateType.equals(DATE_TYPE_HOUR)) {
            return localDateTime.plusHours(number);
        }
        if (dateType.equals(DATE_TYPE_MINUTE)) {
            return localDateTime.plusMinutes(number);
        }
        if (dateType.equals(DATE_TYPE_SECONDS)) {
            return localDateTime.plusSeconds(number);
        }
        return localDateTime;
    }

    /**
     * 获取指定日期月份第一天/最后一天
     *
     * @param dateStr 日期字符串(格式:yyyy-MM-dd)
     * @param isFirst true 第一天,false 最后一天
     * @return 日期 org.joda.time.LocalDate
     */
    public static LocalDate getFirstOrLastDayOfMonth(String dateStr, boolean isFirst) {
        LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
        return localDate.withDayOfMonth(isFirst ? localDate.dayOfMonth().getMinimumValue() : localDate.dayOfMonth().getMaximumValue());
    }

    /**
     * 获取指定日期所在星期第一天/最后一天的日期 (规定:第一天为周一,最后一天为周日)
     *
     * @param dateStr 日期字符串(格式:yyyy-MM-dd)
     * @param isFirst true 第一天,false 最后一天
     * @return 日期 org.joda.time.LocalDate
     */
    public static LocalDate getFirstOrLastDayOfWeek(String dateStr, boolean isFirst) {
        LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
        return isFirst ? localDate.withDayOfWeek(localDate.dayOfWeek().getMinimumValue()) : localDate.withDayOfWeek(localDate.dayOfWeek().getMaximumValue());
    }

    /**
     * 获取指定日期年份第一天/最后一天
     *
     * @param dateStr 日期字符串(格式:yyyy-MM-dd)
     * @param isFirst true 第一天,false 最后一天
     * @return 日期 org.joda.time.LocalDate
     */
    public static LocalDate getFirstOrLastDayOfYear(String dateStr, boolean isFirst) {
        LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
        return isFirst ? localDate.withDayOfYear(localDate.dayOfYear().getMinimumValue()) : localDate.withDayOfYear(localDate.dayOfYear().getMaximumValue());
    }

    /**
     * 获取指定日期的虽在年份的第一天
     *
     * @param dateStr 日期字符串(格式:yyyy-MM-dd)
     * @return 日期 org.joda.time.LocalDate
     */
    public static LocalDate getFirstDayOfYear(String dateStr) {
        LocalDate localDate = new LocalDate(LocalDate.parse(dateStr, DateTimeFormat.forPattern(yyyyMMdd)));
        return localDate.withDayOfYear(localDate.dayOfYear().getMinimumValue());
    }

    /**
     * 获取当前日期字符串
     *
     * @return 返回格式为:yyyy-MM-dd
     */
    public static String getNowYMd() {
        return LocalDate.now().toString(yyyyMMdd);
    }

    /**
     * 获取当前日期时间字符串
     *
     * @return 返回值格式为:yyyy-MM-dd HH:mm:ss
     */
    public static String getNowYMdHms() {
        return LocalDateTime.now().toString(yyyyMMddHHmmss);
    }

    /**
     * 返回当前日期中文写法(包含 日期-星期-时间)
     *
     * @return 结果实例:2021年6月27日 星期日 下午07时16分02秒
     */
    public static String getNowFullDateTime() {
        return LocalDateTime.now().toString(DateTimeFormat.fullDateTime());
    }

    /**
     * 返回当前日期中文写法(包含 日期-时间)
     *
     * @return 结果实例:2021年6月27日 下午07时16分02秒
     */
    public static String getNowLongDateTime() {
        return LocalDateTime.now().toString(DateTimeFormat.longDateTime());
    }

    /**
     * 返回当前日期中文写法(只包含 日期)
     *
     * @return 结果实例:2021年6月27日
     */
    public static String getNowLongDate() {
        return LocalDateTime.now().toString(DateTimeFormat.longDate());
    }

    /**
     * 返回当前日期中文写法(只包含 时间)
     *
     * @return 结果实例:下午07时20分00秒
     */
    public static String getNowLongTime() {
        return LocalDateTime.now().toString(DateTimeFormat.longTime());
    }

    /**
     * 获取某时间段内所有周的列表(开始时间,结束时间)
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return 所有周列表
     */
    public static List<String[]> getWeekList(Date startDate, Date endDate) {
        List<String[]> weekList = new ArrayList<>();
        //转换成joda-time的对象
        DateTime firstDay = new DateTime(startDate).dayOfWeek().withMinimumValue();
        DateTime lastDay = new DateTime(endDate).dayOfWeek().withMaximumValue();
        //计算两日期间的区间天数
        Period p = new Period(firstDay, lastDay, PeriodType.days());
        int days = p.getDays();
        if (days > 0) {
            int weekLength = 7;
            for (int i = 0; i < days; i = i + weekLength) {
                String monDay = firstDay.plusDays(i).toString(yyyyMMdd);
                String sunDay = firstDay.plusDays(i + 6).toString(yyyyMMdd);
                String[] week = {monDay, sunDay};
                weekList.add(week);
            }
        }
        return weekList;
    }

    /**
     * 根据不同的周期类型(年月日时分秒周),计算相隔多少个周期
     *
     * @param localDateTime1 第一个日期
     * @param localDateTime2 第二个日期
     * @return 正数:第一个日期 < 第二个日期;负数:第一个日期 > 第二个日期
     */
    public static int betweenDays(LocalDateTime localDateTime1, LocalDateTime localDateTime2, String dateType) {
        if (localDateTime1.isEqual(localDateTime2)) {
            return 0;
        }
        if (dateType.equals(DATE_TYPE_HOUR)) {
            return Hours.hoursBetween(localDateTime1, localDateTime2).getHours();
        }
        if (dateType.equals(DATE_TYPE_MINUTE)) {
            return Minutes.minutesBetween(localDateTime1, localDateTime2).getMinutes();
        }
        if (dateType.equals(DATE_TYPE_SECONDS)) {
            return Seconds.secondsBetween(localDateTime1, localDateTime2).getSeconds();
        }
        if (dateType.equals(DATE_TYPE_DAY)) {
            return Days.daysBetween(localDateTime1, localDateTime2).getDays();
        }
        if (dateType.equals(DATE_TYPE_WEEK)) {
            return Weeks.weeksBetween(localDateTime1, localDateTime2).getWeeks();
        }
        if (dateType.equals(DATE_TYPE_MONTH)) {
            return Months.monthsBetween(localDateTime1, localDateTime2).getMonths();
        }
        if (dateType.equals(DATE_TYPE_YEAR)) {
            return Years.yearsBetween(localDateTime1, localDateTime2).getYears();
        }
        return 0;
    }

    public static void main(String[] args) {
//        System.out.println(isAfterPayDay(new DateTime()));
//        System.out.println(daysToNewYear(new LocalDate()));
//        System.out.println(isRentalOverdue(new DateTime()));
//        System.out.println(getBirthMonthTextEn(new LocalDate()));
//        System.out.println(getBirthMonthTextCn(new LocalDate()));
//        System.out.println(getBirthMonthNumber(new LocalDate()));
//        System.out.println(toLocalDate(new Date()));
//        System.out.println(toLocalDate("2021-12-31").minusDays(2));
//        System.out.println(toLocalDateTime(new Date()));
//        System.out.println(toLocalDateTime("2021-12-31 10:23:59").plusDays(2));
//        System.out.println(new LocalDate().year().isLeap());
//        System.out.println(isLeap(new LocalDate(), DATE_TYPE_YEAR));
//        System.out.println(isLeap(new LocalDate(), DATE_TYPE_DAY));
//        System.out.println(plus(new LocalDateTime(), DATE_TYPE_DAY, 20));

//        System.out.println(new LocalDateTime().year().addToCopy(20));// 20年后的此刻
//        System.out.println(new LocalDateTime().monthOfYear().addToCopy(20)); // 20个月后的此刻
//        System.out.println(new LocalDateTime().dayOfYear().addToCopy(20));// 20日后的此刻
//        System.out.println(new LocalDateTime().dayOfWeek().addToCopy(20));// 20日后的此刻

//        System.out.println(getFirstOrLastDayOfMonth("2021-06-01", false)); // 2021-06-30
//        System.out.println(getFirstOrLastDayOfMonth("2021-02-01", false)); // 2021-02-28
//        System.out.println(getFirstOrLastDayOfMonth("2421-12-01", false)); // 2021-12-31
//        System.out.println(getFirstOrLastDayOfWeek("2021-06-01", false)); // 2021-06-06
//        System.out.println(getFirstDayOfYear("2021-12-21")); // 2021-01-01
//        System.out.println(getFirstOrLastDayOfYear("2021-01-01", false)); // 2021-12-31

//        System.out.println(getNowYMd());
//        System.out.println(getNowYMdHms());
//        System.out.println(getNowLongDateTime());
//        System.out.println(getNowLongDate());
//        System.out.println(getNowLongTime());

//        getWeekList(new Date(), toLocalDate("2021-03-01").toDate()).forEach(it -> {
//            for (String s : it) {
//                System.out.print(s + "\t");
//            }
//            System.out.println();
//        });
//        System.out.println(System.currentTimeMillis());
        System.out.println(betweenDays(toLocalDateTime("2021-06-01 00:00:00"), toLocalDateTime("2021-06-10 00:00:00"), DATE_TYPE_DAY));
    }
}

三、附录

  1. 官网地址:Joda-Time - Home
  2. 官方地址:Overview (Joda-Time 2.10.11-SNAPSHOT API)
  3. 博客说明文档:使用JodaTime处理时间_悠闲咖啡007的博客-CSDN博客_joda time