Java日期时间API系列26—–Jdk8中java.time包中的新的日期时间API类,YearMonth类的源码,转换和应用。

Java8中为年月新增了类YearMonth,可以用来表示卡片过期时间等问题。

1.YearMonth

默认格式为:2007-12

1.1 部分源码

*
 * @implSpec
 * This class is immutable and thread-safe.
 *
 * @since 1.8
 */
public final class YearMonth
        implements Temporal, TemporalAdjuster, Comparable, Serializable {

    /**
     * Serialization version.
     */
    private static final long serialVersionUID = 4183400860270640070L;
    /**
     * Parser.
     */
    private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
        .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
        .appendLiteral('-')
        .appendValue(MONTH_OF_YEAR, 2)
        .toFormatter();

    /**
     * The year.
     */
    private final int year;
    /**
     * The month-of-year, not null.
     */
    private final int month;

通过源码可以看出使用final修饰YearMonth,YearMonth是线程安全类,同时实现了Temporal, TemporalAdjuster, Comparable, Serializable接口,有属性读取,设置和加减等功能。

 

 

 1.2 创建和基本使用

        YearMonth yearMonth = YearMonth.now();
        YearMonth yearMonth2 = YearMonth.of(2020, 4);
        
        System.out.println(yearMonth);
        System.out.println(yearMonth2);
        YearMonth yearMonth3 = YearMonth.parse("2020-05");
        System.out.println(yearMonth3);
        
        YearMonth yearMonth4 = yearMonth3.plusMonths(1);
        System.out.println(yearMonth4);

输出:

2020-03
2020-04
2020-05
2020-06

 

2.应用

2.1 转换

如Date转YearMonth,YearMonth转Date等
    /**
     * Date转YearMonth
     * @param date
     * @return
     */
    public static YearMonth toYearMonth(Date date){
        LocalDate localDate = toLocalDate(date);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * LocalDateTime转YearMonth
     * @param localDateTime
     * @return
     */
    public static YearMonth toYearMonth(LocalDateTime localDateTime){
        LocalDate localDate = toLocalDate(localDateTime);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * LocalDate转YearMonth
     * @param localDate
     * @return
     */
    public static YearMonth toYearMonth(LocalDate localDate){
        Objects.requireNonNull(localDate, "localDate");
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * Instant转YearMonth
     * @param instant
     * @return
     */
    public static YearMonth toYearMonth(Instant instant){
        LocalDate localDate = toLocalDate(instant);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }
    
    /**
     * ZonedDateTime转YearMonth
     * @param zonedDateTime
     * @return
     */
    public static YearMonth toYearMonth(ZonedDateTime zonedDateTime){
        LocalDate localDate = toLocalDate(zonedDateTime);
        return YearMonth.of(localDate.getYear(), localDate.getMonthValue());
    }

    /**
     * YearMonth转Date
     * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28
     * 如果要转换为当月最后一天,可以使用下面方法:toDateEndOfMonth(YearMonth)
     * @param yearMonth
     * @param dayOfMonth
     * @return
     */
    public static Date toDate(YearMonth yearMonth, int dayOfMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return toDate(yearMonth.atDay(dayOfMonth));
    }
    
    /**
     * YearMonth转Date,转换为当月第一天
     * @param yearMonth
     * @return
     */
    public static Date toDateStartOfMonth(YearMonth yearMonth) {
        return toDate(yearMonth, 1);
    }
    
    /**
     * YearMonth转Date,转换为当月最后一天
     * @param yearMonth
     * @return
     */
    public static Date toDateEndOfMonth(YearMonth yearMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return toDate(yearMonth.atEndOfMonth());
    }

    /**
     * YearMonth转LocalDate
     * 注意dayOfMonth范围:1到31之间,最大值根据月份确定特殊情况,如2月闰年29,非闰年28
     * 如果要转换为当月最后一天,可以使用下面方法:toLocalDateEndOfMonth(YearMonth)
     * @param yearMonth
     * @param dayOfMonth
     * @return
     */
    public static LocalDate toLocalDate(YearMonth yearMonth, int dayOfMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return yearMonth.atDay(dayOfMonth);
    }
    
    /**
     * YearMonth转LocalDate,转换为当月第一天
     * @param yearMonth
     * @return
     */
    public static LocalDate toLocalDateStartOfMonth(YearMonth yearMonth) {
        return toLocalDate(yearMonth, 1);
    }
    
    /**
     * YearMonth转LocalDate,转换为当月最后一天
     * @param yearMonth
     * @return
     */
    public static LocalDate toLocalDateEndOfMonth(YearMonth yearMonth) {
        Objects.requireNonNull(yearMonth, "yearMonth");
        return yearMonth.atEndOfMonth();
    }

 

测试代码:

    @Test
    public void yearMonthConverterTest(){
        System.out.println("===================yearMonthConverterTest=====================");
        Date date = new Date();
        System.out.println(date);
        YearMonth yearMonth = DateTimeConverterUtil.toYearMonth(date);
        System.out.println(yearMonth);
        
        Date date1 = DateTimeConverterUtil.toDate(yearMonth, 15);
        //转换为当月第一天
        Date date2 = DateTimeConverterUtil.toDateStartOfMonth(yearMonth);
        //转换为当月最后一天
        Date date3 = DateTimeConverterUtil.toDateEndOfMonth(yearMonth);
        System.out.println(date1);
        System.out.println(date2);
        System.out.println(date3);
        
        LocalDate LocalDate1 = DateTimeConverterUtil.toLocalDate(yearMonth, 15);
        //转换为当月第一天
        LocalDate LocalDate2 = DateTimeConverterUtil.toLocalDateStartOfMonth(yearMonth);
        //转换为当月最后一天
        LocalDate LocalDate3 = DateTimeConverterUtil.toLocalDateEndOfMonth(yearMonth);
        System.out.println(LocalDate1);
        System.out.println(LocalDate2);
        System.out.println(LocalDate3);
    }

 

输出:

===================yearMonthConverterTest=====================
Fri Mar 20 23:41:41 CST 2020
2020-03
Sun Mar 15 00:00:00 CST 2020
Sun Mar 01 00:00:00 CST 2020
Tue Mar 31 00:00:00 CST 2020
2020-03-15
2020-03-01
2020-03-31

 

2.2 计算

获取起始日期中间的日期列表,获取指定月份的日期列表,判断是否过期等等

    /**
     * 获取指定区间的时间列表,包含起始
     * @param startInclusive
     * @param endInclusive
     * @return
     */
    public static List getLocalDateTimeList(LocalDateTime startInclusive, LocalDateTime endInclusive){
        Objects.requireNonNull(startInclusive, "startInclusive");
        Objects.requireNonNull(endInclusive, "endInclusive");
        if(startInclusive.isAfter(endInclusive)){
            throw new DateTimeException("startInclusive must before or equal endInclusive!");
        }
        List localDateTimeList = new ArrayList();
        long days = betweenTotalDays(startInclusive, endInclusive)+1;
        for(long i=0; i){
            localDateTimeList.add(startInclusive.plusDays(i));
        }
        return localDateTimeList;
    }
    
    /**
     * 获取指定区间的时间列表,包含起始
     * @param startInclusive
     * @param endInclusive
     * @return
     */
    public static List getLocalDateList(LocalDate startInclusive, LocalDate endInclusive){
        return getLocalDateTimeList(DateTimeConverterUtil.toLocalDateTime(startInclusive),
                DateTimeConverterUtil.toLocalDateTime(endInclusive)).stream()
                        .map(localDateTime -> localDateTime.toLocalDate()).collect(Collectors.toList());
    }
    
    /**
     * 获取指定区间的时间列表,包含起始
     * @param startInclusive
     * @param endInclusive
     * @return
     */
    public static List getDateList(Date startInclusive, Date endInclusive){
        return getLocalDateTimeList(DateTimeConverterUtil.toLocalDateTime(startInclusive),
                DateTimeConverterUtil.toLocalDateTime(endInclusive)).stream()
                        .map(localDateTime -> DateTimeConverterUtil.toDate(localDateTime)).collect(Collectors.toList());
    }
    
    /**
     *  获取指定年月的所有日期列表
     * @param YearMonth
     * @return
     */
    public static List getLocalDateList(YearMonth yearMonth){
        Objects.requireNonNull(yearMonth, "yearMonth");
        List localDateList = new ArrayList();
        long days = yearMonth.lengthOfMonth();
        LocalDate localDate = DateTimeConverterUtil.toLocalDateStartOfMonth(yearMonth);
        for(long i=0; i){
            localDateList.add(plusDays(localDate, i));
        }
        return localDateList;
    }
    
    /**
     *  获取指定年月的所有日期列表
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static List getLocalDateList(String yearMonthStr){
        Objects.requireNonNull(yearMonthStr, "yearMonthStr");
        YearMonth yearMonth = YearMonth.parse(yearMonthStr);
        return getLocalDateList(yearMonth);
    }
    
    /**
     *  获取指定年月的所有日期列表
     * @param yearMonth
     * @return
     */
    public static List getLocalDateTimeList(YearMonth yearMonth){
        return getLocalDateList(yearMonth).stream()
                .map(localDate -> DateTimeConverterUtil.toLocalDateTime(localDate)).collect(Collectors.toList());
    }    
    
    /**
     *  获取指定年月的所有日期列表
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static List getLocalDateTimeList(String yearMonthStr){
        return getLocalDateList(yearMonthStr).stream()
                .map(localDate -> DateTimeConverterUtil.toLocalDateTime(localDate)).collect(Collectors.toList());
    }
    
    /**
     * 获取指定年月的所有日期列表
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static List getDateList(String yearMonthStr){
        return getLocalDateList(yearMonthStr).stream().map(localDate -> DateTimeConverterUtil.toDate(localDate))
                .collect(Collectors.toList());
    }
    
    /**
     * 判断是否过期,(输入年月小于当前年月)
     * @param yearMonth
     * @return
     */
    public static boolean isExpiry(YearMonth yearMonth){
        Objects.requireNonNull(yearMonth, "yearMonth");
        if(yearMonth.isBefore(YearMonth.now())){
            return true;
        }
        return false;
    }
    
    /**
     * 判断是否过期,(输入年月小于当前年月)
     * @param yearMonthStr yyyy-MM
     * @return
     */
    public static boolean isExpiry(String yearMonthStr){
        Objects.requireNonNull(yearMonthStr, "yearMonthStr");
        YearMonth yearMonth = YearMonth.parse(yearMonthStr);
        return isExpiry(yearMonth);
    }

 

测试代码:

    /**
     * yearMonth测试
     */
    @Test
    public void yearMonthTest(){
        //是否过期
        System.out.println(DateTimeCalculatorUtil.isExpiry("2020-03"));
        
        //获取指定年月的所有日期列表
        List dateList = DateTimeCalculatorUtil.getDateList("2020-03");
        dateList.stream().forEach(date->{
            System.out.println(DateTimeFormatterUtil.formatToDateStr(date));
        });
        
        System.out.println("========================");

        //获取指定区间的时间列表,包含起始
        List dateList2 = DateTimeCalculatorUtil.getDateList(dateList.get(0), dateList.get(dateList.size()-1));
        dateList2.stream().forEach(date->{
            System.out.println(DateTimeFormatterUtil.formatToDateStr(date));
        });
        
    }

 

输出:

false
2020-03-01
2020-03-02
2020-03-03
2020-03-04
2020-03-05
2020-03-06
2020-03-07
2020-03-08
2020-03-09
2020-03-10
2020-03-11
2020-03-12
2020-03-13
2020-03-14
2020-03-15
2020-03-16
2020-03-17
2020-03-18
2020-03-19
2020-03-20
2020-03-21
2020-03-22
2020-03-23
2020-03-24
2020-03-25
2020-03-26
2020-03-27
2020-03-28
2020-03-29
2020-03-30
2020-03-31
========================
2020-03-01
2020-03-02
2020-03-03
2020-03-04
2020-03-05
2020-03-06
2020-03-07
2020-03-08
2020-03-09
2020-03-10
2020-03-11
2020-03-12
2020-03-13
2020-03-14
2020-03-15
2020-03-16
2020-03-17
2020-03-18
2020-03-19
2020-03-20
2020-03-21
2020-03-22
2020-03-23
2020-03-24
2020-03-25
2020-03-26
2020-03-27
2020-03-28
2020-03-29
2020-03-30
2020-03-31

 

源代码地址:https://github.com/xkzhangsan/xk-time