Java -- JodaTime第三方库操作时间

Posted MinggeQingchun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java -- JodaTime第三方库操作时间相关的知识,希望对你有一定的参考价值。

Java自带日期格式化工具DateFormat ,但是DateFormat 的所有实现,包括 SimpleDateFormat 都不是线程安全的,因此不应该在多线程序中使用,除非是在对外线程安全的环境中使用,如将 SimpleDateFormat 限制在 ThreadLocal 中。如果不这么做,在解析或者格式化日期的时候,可能会获取到一个不正确的结果。所以,通常我们使用第三方库Joda Time来进行时间相关的操作

一、导入JodaTime

1、在Maven中

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

2、在Gradle中

compile 'joda-time:joda-time:2.10.5'

二、JodaTime核心类

使用最多的五个日期时间类:

- Instant - 不可变的类,用来表示时间轴上一个瞬时的点(时间戳

- DateTime - 不可变的类,用来替换JDK的Calendar类

- LocalDate - 不可变的类,表示一个本地的日期,而不包含时间部分(没有时区信息)

- LocalTime - 不可变的类,表示一个本地的时间,而不包含日期部分(没有时区信息)

- LocalDateTime - 不可变的类,表示一个本地的日期-时间(没有时区信息) 

// joda创建时间对象时需要指定时区,如果不指定,默认会把时区设置为运行代码的机器所在的时区
        DateTime dateTime0 = new DateTime(2022, 7, 3, 11, 0, 0).withZone(DateTimeZone.forID("Asia/Shanghai"));
        System.out.println("dateTime0----" + dateTime0.toDate());

三、DateTime实例

当使用JodaTime的时候,首先你要获取一个DateTime实例,然后用它的其他方法串联起来实现强大的功能

/**
         * 1、当使用JodaTime的时候,首先你要获取一个DateTime实例,然后用它的其他方法串联起来实现强大的功能。想要获取一个DateTime实例,你有很多种方式
         * */
        // 方式1:使用系统时间构造DateTime实例
        DateTime dateTime = new DateTime();

        // 方式2:使用具体的时间构造DateTime实例,该方法有许多重载版本
        DateTime dateTime1 = new DateTime(
                2022, // year
                1,    // month
                1,    // day
                0,    // hour (midnight is zero)
                0,    // minute
                0,    // second
                0     // milliseconds
        );

        // 方式3:使用Calendar构造DateTime实例
        DateTime dateTime2 = new DateTime(Calendar.getInstance());
        System.out.println("dateTime2----" + dateTime2.toDate());

        // 方式4:使用其他DateTime实例构造DateTime实例
        DateTime dateTime3 = new DateTime(dateTime);
        System.out.println("dateTime3----" + dateTime3.toDate());

        // 方式5:使用字符串构造DateTime实例
        DateTime dateTime4 = new DateTime("2022-01-26T13:30:00-06:00");
        DateTime dateTime5 = new DateTime("2022-01-26");
        System.out.println("dateTime4----" + dateTime4.toDate());
        System.out.println("dateTime5----" + dateTime5.toDate());

四、DateTime方法

DateTime中有许多的方法,这里我们将常用的方法分成两类。一类是在方法中返回DateTime的那种,一类是在方法中返回Property类型的那种。显然,后面的那种继续串联操作的话,就需要调用Property的实例方法了

1、返回DateTime

/**
         * 2、DateTime的方法
         * DateTime中有许多的方法,这里我们将常用的方法分成两类。
         * 一类是在方法中返回DateTime的那种,一类是在方法中返回Property类型的那种。
         * 后面的那种继续串联操作的话,就需要调用Property的实例方法了
         * */
        // 指定的时间单位上面增加指定的值
        DateTime dateTime00 = dateTime.plusDays(1);
        System.out.println("dateTime00----" + dateTime00);

        // 指定的时间单位上面减少指定的值
        DateTime dateTime6 = dateTime.minusDays(1);
        System.out.println("dateTime6----" + dateTime6);

        // 除了增减日期还可以直接指定它的指定时间单位上面的值
        DateTime dateTime7 = dateTime.withYear(2020);
        System.out.println("dateTime7----" + dateTime7);

        // 按照指定的格式输出日期
        System.out.println(dateTime.toString("E MM/dd/yyyy HH:mm:ss.SSS"));

2、返回Property

以通过DateTime实例的millisOfDay() dayOfYear() minuteOfDay()等一些列方法可以获取到该DateTime的一个Property实例,然后可以通过调用Property的方法再获取一个DateTime实例。也就是说,实际上调用DateTime的方法获取Property实例是为了对指定的时间位置的信息进行修改。比如,对“日”进行修改,对“年”进行修改等等。修改了之后还是要获取一个DateTime实例,然后再继续进行后续的操作。

实际上每次调用DateTime的方法获取Property实例的时候,都会将当前的DateTime作为参数传入。然后当调用了指定的方法之后又会调用DateTime实例的withMillis()方法判断时间是否发生变化,如果发生了变化就创建一个新实例并返回

/**
         * 3、使用Property
         * 可以通过DateTime实例的millisOfDay() dayOfYear() minuteOfDay()等一些列方法可以获取到该DateTime的一个Property实例,然后可以通过调用Property的方法再获取一个DateTime实例。也就是说,实际上调用DateTime的方法获取Property实例是为了对指定的时间位置的信息进行修改。比如,对“日”进行修改,对“年”进行修改等等。修改了之后还是要获取一个DateTime实例,然后再继续进行后续的操作。
         * 实际上每次调用DateTime的方法获取Property实例的时候,都会将当前的DateTime作为参数传入。然后当调用了指定的方法之后又会调用DateTime实例的withMillis()方法判断时间是否发生变化,如果发生了变化就创建一个新实例并返回
         * */
        // 这里先用dayOfMonth获取一个Property实例,然后调用它的withMaximumValue方法
        // 它的含义是指定日期的其他日期不变,月份变成最大的之后返回一个DateTime,即如果传入的是2022年5月1日,将返回2022年5月31日,年,月,秒等位置不变,日变成该月最大的。
        DateTime dateTime000 = dateTime.dayOfMonth().withMaximumValue();
        DateTime dateTime111 = dateTime.dayOfMonth().withMinimumValue();
        System.out.println("dateTime000----" + dateTime000);
        System.out.println("dateTime111----" + dateTime111);

3、其他静态方法 

/**
         * 4、其他静态方法
         * */
        System.out.println("Days.daysBetween(dateTime1, dateTime).getDays()----" + Days.daysBetween(dateTime1, dateTime).getDays());
        System.out.println("Months.monthsBetween(dateTime1, dateTime).getMonths()----" + Months.monthsBetween(dateTime1, dateTime).getMonths());
        System.out.println("Years.yearsBetween(dateTime1, dateTime).getYears()----" + Years.yearsBetween(dateTime1, dateTime).getYears());

4、封装工具类

package com.mycompany.joda;

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

import java.util.Date;

public class JodaTimeUtil 

    private static final String PATTERN_STANDARD = "yyyy-MM-dd HH:mm:ss";
    private static final String PATTERN_DATE = "yyyy-MM-dd";
    private static final String PATTERN_TIME = "HH:mm:ss";

    /**
     * date类型 -> string类型
     *
     * @param date
     * @return
     */
    public static String date2Str(Date date) 
        if (date == null) 
            return "";
        
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(PATTERN_STANDARD);
    

    /**
     * date类型 -> string类型
     *
     * @param date
     * @param formatPattern
     * @return
     */
    public static String date2Str(Date date, String formatPattern) 
        if (date == null) 
            return "";
        
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(formatPattern);
    

    /**
     * string类型 -> date类型
     *
     * @param timeStr
     * @return
     */
    public static Date str2Date(String timeStr) 
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(PATTERN_STANDARD);
        DateTime dateTime = dateTimeFormatter.parseDateTime(timeStr);
        return dateTime.toDate();
    

    /**
     * 获取指定时间
     * @param year 年
     * @param month 月
     * @param day 日
     * @param hour 时
     * @param minute 分
     * @param seconds 秒
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getAssignedDateTime(Integer year, Integer month, Integer day, Integer hour, Integer minute, Integer seconds) 
        DateTime dt = new DateTime(year, month, day, hour, minute, seconds);
        String date = dt.toString(PATTERN_STANDARD);
        return date;
    
    /**
     * 获取指定日期
     * @param year
     * @param month
     * @param day
     * @return
     */
    public static String getAssignedDate(Integer year, Integer month, Integer day) 
        LocalDate dt = new LocalDate(year, month, day);
        String date = dt.toString(PATTERN_DATE);
        return date;
    
    /**
     * 获取指定时间
     * @param hour
     * @param minutes
     * @param seconds
     * @return
     */
    public static String getAssignedTime(Integer hour, Integer minutes, Integer seconds) 
        LocalTime dt = new LocalTime(hour, minutes, seconds);
        String date = dt.toString(PATTERN_TIME);
        return date;
    
    /**
     * 判断date日期是否过期(与当前时刻比较)
     *
     * @param date
     * @return
     */
    public static boolean isTimeExpired(Date date) 
        if (null == date) 
            return true;
        
        String timeStr = date2Str(date);
        return isBeforeNow(timeStr);
    

    /**
     * 判断date日期是否过期(与当前时刻比较)
     *
     * @param timeStr
     * @return
     */
    public static boolean isTimeExpired(String timeStr) 
        if (StringUtils.isBlank(timeStr)) 
            return true;
        

        return isBeforeNow(timeStr);
    

    /**
     * 判断timeStr是否在当前时刻之前
     *
     * @param timeStr
     * @return
     */
    private static boolean isBeforeNow(String timeStr) 
        DateTimeFormatter format = DateTimeFormat.forPattern(PATTERN_STANDARD);
        DateTime dateTime = DateTime.parse(timeStr, format);
        return dateTime.isBeforeNow();
    


    /**
     * 加天数
     *
     * @param date
     * @param days
     * @return
     */
    private static Date plusDays(Date date, Integer days) 
        if (null == date) 
            return null;
        
        days = null == days ? 0 : days;

        DateTime dateTime = new DateTime(date);
        dateTime = dateTime.plusDays(days);

        return dateTime.toDate();
    

    /**
     * 减天数
     *
     * @param date
     * @param days
     * @return
     */
    private static Date minusDays(Date date, Integer days) 
        if (null == date) 
            return null;
        
        days = null == days ? 0 : days;

        DateTime dateTime = new DateTime(date);
        dateTime = dateTime.minusDays(days);

        return dateTime.toDate();
    


    /**
     * 加分钟
     *
     * @param date
     * @param minutes
     * @return
     */
    private static Date plusMinutes(Date date, Integer minutes) 
        if (null == date) 
            return null;
        
        minutes = null == minutes ? 0 : minutes;

        DateTime dateTime = new DateTime(date);
        dateTime = dateTime.plusMinutes(minutes);

        return dateTime.toDate();
    

    /**
     * 减分钟
     *
     * @param date
     * @param minutes
     * @return
     */
    private static Date minusMinutes(Date date, Integer minutes) 
        if (null == date) 
            return null;
        
        minutes = null == minutes ? 0 : minutes;

        DateTime dateTime = new DateTime(date);
        dateTime = dateTime.minusMinutes(minutes);

        return dateTime.toDate();
    

    /**
     * 加月份
     *
     * @param date
     * @param months
     * @return
     */
    private static Date plusMonths(Date date, Integer months) 
        if (null == date) 
            return null;
        
        months = null == months ? 0 : months;

        DateTime dateTime = new DateTime(date);
        dateTime = dateTime.plusMonths(months);

        return dateTime.toDate();
    

    /**
     * 减月份
     *
     * @param date
     * @param months
     * @return
     */
    private static Date minusMonths(Date date, Integer months) 
        if (null == date) 
            return null;
        
        months = null == months ? 0 : months;

        DateTime dateTime = new DateTime(date);
        dateTime = dateTime.minusMonths(months);

        return dateTime.toDate();
    

    /**
     * 判断target是否在开始和结束时间之间
     *
     * @param target
     * @param startTime
     * @param endTime
     * @return
     */
    public static boolean isBetween(Date target, Date startTime, Date endTime) 
        if (null == target || null == startTime || null == endTime) 
            return false;
        

        DateTime dateTime = new DateTime(target);
        return dateTime.isAfter(startTime.getTime()) && dateTime.isBefore(endTime.getTime());
    

    /**
     * 获取当前系统时间
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String getCurrentDateTime() 
        DateTime dt = new DateTime();
        String time = dt.toString(PATTERN_STANDARD);
        return time;
    
    /**
     * 获取当前日期
     * @return
     */
    public static String getCurrentDate() 
        DateTime dt = new DateTime();
        String date = dt.toString(PATTERN_DATE);
        return date;
    
    /**
     * 获取系统当前时间按照指定格式返回
     * @return
     */
    public static String getCurrentTime() 
        DateTime dt = new DateTime();
        String time = dt.toString(PATTERN_TIME);
        return time;
    
    /**
     * 获取当前是一周星期几
     * @return
     */
    public static String getWeek() 
        DateTime dts = new DateTime();
        String week = null;
        switch (dts.getDayOfWeek()) 
            case DateTimeConstants.SUNDAY:
                week = "星期日";
                break;

            case DateTimeConstants.MONDAY:
                week = "星期一";
                break;

            case DateTimeConstants.TUESDAY:
                week = "星期二";
                break;
            case DateTimeConstants.WEDNESDAY:
                week = "星期三";
                break;
            case DateTimeConstants.THURSDAY:
                week = "星期四";
                break;
            case DateTimeConstants.FRIDAY:
                week = "星期五";
                break;
            case DateTimeConstants.SATURDAY:
                week = "星期六";
            default:
                break;
        
        return week;
    
    /**
     * 获取指定时间是一周的星期几
     * @param year
     * @param month
     * @param day
     * @return
     */
    public static String getWeek(Integer year, Integer month, Integer day) 
        LocalDate dts = new LocalDate(year, month, day);
        String week = null;
        switch (dts.getDayOfWeek()) 
            case DateTimeConstants.SUNDAY:
                week = "星期日";
                break;
            case DateTimeConstants.MONDAY:
                week = "星期一";
                break;
            case DateTimeConstants.TUESDAY:
                week = "星期二";
                break;
            case DateTimeConstants.WEDNESDAY:
                week = "星期三";
                break;
            case DateTimeConstants.THURSDAY:
                week = "星期四";
                break;
            case DateTimeConstants.FRIDAY:
                week = "星期五";
                break;
            case DateTimeConstants.SATURDAY:
                week = "星期六";
                break;

            default:
                break;
        
        return week;
    
    /**
     * 计算两个时间相差多少天
     * @param startDate
     * @param endDate
     * @return
     */
    public static Integer diffDay(Date startDate, Date endDate) 
        if (startDate == null || endDate == null) 
            return null;
        
        DateTime dt1 = new DateTime(startDate);
        DateTime dt2 = new DateTime(endDate);
        int day = Days.daysBetween(dt1, dt2).getDays();
        return Math.abs(day);
    


参考链接

Java第三方库JodaTime的具体使用是怎样的_编程设计_IT干货网

以上是关于Java -- JodaTime第三方库操作时间的主要内容,如果未能解决你的问题,请参考以下文章

我应该使用 Java 日期和时间类还是使用像 Joda Time 这样的 3rd 方库?

鸿蒙开源第三方组件——日期和时间处理组件JodaTime-ohos

Java - 使用DBUtils BeanListHandler将查询中的所有日期转换为JodaTime的DateTime

java JodaTime

在 Java 8 中计算两个日期之间的天数

使用 ObjectMapper 为 JodaTime 设置时区偏移的 Jackson DateTime 格式