Java8中为月日新增了类MonthDay,可以用来处理生日,节日、纪念日和星座等周期性问题。

1.MonthDay

  特别需要注意的:它的默认打印格式会带前缀"--" ,比如--12-03,同样的默认解析格式也需要加前缀。

1.1 部分源码

 * @implSpec
* This class is immutable and thread-safe.
*
* @since 1.8
*/
public final class MonthDay
implements TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable { /**
* Serialization version.
*/
private static final long serialVersionUID = -939150713474957432L;
/**
* Parser.
*/
private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
.appendLiteral("--")
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.toFormatter(); /**
* The month-of-year, not null.
*/
private final int month;
/**
* The day-of-month.
*/
private final int day;

通过源码可以看出使用final修饰MonthDay,MonthDay是线程安全类,同时实现了TemporalAccessor, TemporalAdjuster, Comparable<MonthDay>, Serializable接口,有属性读取和设置等功能,但由于没有年部分,闰年2月29日的原因,没有加减功能。

1.2 创建方式

     MonthDay monthDay1 = MonthDay.now();
System.out.println(monthDay1); MonthDay monthDay2 = MonthDay.of(12, 3);
System.out.println(monthDay2);

输出:

--02-29
--12-03

1.3 解析

System.out.println(MonthDay.parse("--12-03"));

2. 应用

对比相同月日和推算等

2.1 应用代码

    /**
* 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
* @param localDate1
* @param monthDay
* @return
*/
public static boolean isSameMonthDay(LocalDate localDate1, MonthDay monthDay){
Objects.requireNonNull(localDate1, "localDate1");
Objects.requireNonNull(monthDay, "monthDay");
return MonthDay.of(localDate1.getMonthValue(), localDate1.getDayOfMonth()).equals(monthDay);
} /**
* 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
* @param localDate1
* @param monthDayStr MM-dd格式
* @return
*/
public static boolean isSameMonthDay(LocalDate localDate1, String monthDayStr){
Objects.requireNonNull(monthDayStr, "monthDayStr");
return isSameMonthDay(localDate1, MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr));
} /**
* 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
* @param localDate1
* @param localDate2
* @return
*/
public static boolean isSameMonthDay(LocalDate localDate1, LocalDate localDate2){
Objects.requireNonNull(localDate2, "localDate2");
return isSameMonthDay(localDate1, MonthDay.of(localDate2.getMonthValue(), localDate2.getDayOfMonth()));
} /**
* 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
* @param date
* @param monthDayStr MM-dd格式
* @return
*/
public static boolean isSameMonthDay(Date date, String monthDayStr){
return isSameMonthDay(DateTimeConverterUtil.toLocalDate(date), monthDayStr);
} /**
* 相同月日比较判断,用于生日,节日等周期性的日期比较判断。
* @param date1
* @param date2
* @return
*/
public static boolean isSameMonthDay(Date date1, Date date2){
Objects.requireNonNull(date1, "date1");
Objects.requireNonNull(date2, "date2");
return isSameMonthDay(DateTimeConverterUtil.toLocalDate(date1), DateTimeConverterUtil.toLocalDate(date2));
} /**
* 相同月日比较判断,与当前日期对比,用于生日,节日等周期性的日期比较判断
* @param monthDayStr MM-dd格式
* @return
*/
public static boolean isSameMonthDayOfNow(String monthDayStr){
return isSameMonthDay(LocalDate.now(), monthDayStr);
} /**
* 下个固定月日相差天数,用于生日,节日等周期性的日期推算
* @param localDate1
* @param month
* @param dayOfMonth
* @return
*/
public static long betweenNextSameMonthDay(LocalDate localDate1, int month, int dayOfMonth) {
Objects.requireNonNull(localDate1, "localDate1");
MonthDay monthDay1 = MonthDay.of(localDate1.getMonthValue(), localDate1.getDayOfMonth());
MonthDay monthDay2 = MonthDay.of(month, dayOfMonth); // localDate1 月日 小于 month dayOfMonth
if (monthDay1.compareTo(monthDay2) == -1) {
return betweenTotalDays(localDate1.atStartOfDay(),
localDate1.withMonth(month).withDayOfMonth(dayOfMonth).atStartOfDay());
} else {
// 闰年2月29
MonthDay leapMonthDay = MonthDay.of(2, 29);
if (leapMonthDay.equals(monthDay2)) {
LocalDate nextLeapYear = nextLeapYear(localDate1);
return betweenTotalDays(localDate1.atStartOfDay(),
nextLeapYear.withMonth(month).withDayOfMonth(dayOfMonth).atStartOfDay());
} else {
LocalDate next = localDate1.plusYears(1);
return betweenTotalDays(localDate1.atStartOfDay(),
next.withMonth(month).withDayOfMonth(dayOfMonth).atStartOfDay());
}
}
} /**
* 下个固定月日相差天数,用于生日,节日等周期性的日期推算
* @param localDate
* @param monthDayStr MM-dd格式
* @return
*/
public static long betweenNextSameMonthDay(LocalDate localDate, String monthDayStr) {
Objects.requireNonNull(monthDayStr, "monthDayStr");
MonthDay monthDay2 = MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr);
return betweenNextSameMonthDay(localDate, monthDay2.getMonthValue(), monthDay2.getDayOfMonth());
} /**
* 下个固定月日相差天数,用于生日,节日等周期性的日期推算
* @param date
* @param monthDayStr MM-dd格式
* @return
*/
public static long betweenNextSameMonthDay(Date date, String monthDayStr) {
Objects.requireNonNull(monthDayStr, "monthDayStr");
MonthDay monthDay2 = MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr);
return betweenNextSameMonthDay(DateTimeConverterUtil.toLocalDate(date), monthDay2.getMonthValue(),
monthDay2.getDayOfMonth());
} /**
* 下个固定月日相差天数,与当前日期对比,用于生日,节日等周期性的日期推算
* @param monthDayStr MM-dd格式
* @return
*/
public static long betweenNextSameMonthDayOfNow(String monthDayStr) {
Objects.requireNonNull(monthDayStr, "monthDayStr");
MonthDay monthDay2 = MonthDay.parse(MONTHDAY_FORMAT_PRE + monthDayStr);
return betweenNextSameMonthDay(LocalDate.now(), monthDay2.getMonthValue(),
monthDay2.getDayOfMonth());
} /**
* 下个固定月日相差日期,用于生日,节日等周期性的日期推算
* @param localDate
* @param monthDayStr MM-dd格式
* @return
*/
public static LocalDate nextSameMonthDay(LocalDate localDate, String monthDayStr){
return localDate.plusDays(betweenNextSameMonthDay(localDate, monthDayStr));
} /**
* 下个固定月日相差日期,用于生日,节日等周期性的日期推算
* @param date
* @param monthDayStr MM-dd格式
* @return
*/
public static Date nextSameMonthDay(Date date, String monthDayStr){
return DateTimeConverterUtil.toDate(nextSameMonthDay(DateTimeConverterUtil.toLocalDate(date), monthDayStr));
} /**
* 下个固定月日相差日期,与当前日期对比,用于生日,节日等周期性的日期推算
* @param monthDayStr MM-dd格式
* @return
*/
public static Date nextSameMonthDayOfNow(String monthDayStr){
return nextSameMonthDay(new Date(), monthDayStr);
}

2.2 测试代码

    /**
* 相同月日对比
*/
@Test
public void sameMonthDayTest(){
Date date = DateTimeCalculatorUtil.getDate(2020, 2, 29);
System.out.println(date); //date的月日部分是否和02-29相等
System.out.println(DateTimeCalculatorUtil.isSameMonthDay(date, "02-29"));
//date的月日部分是否和new Date()的月日部分相等
System.out.println(DateTimeCalculatorUtil.isSameMonthDay(date, new Date()));
//当前时间月日部分是否和02-29相等
System.out.println(DateTimeCalculatorUtil.isSameMonthDayOfNow("02-29")); //date的月日部分和下一个03-05相差天数
System.out.println(DateTimeCalculatorUtil.betweenNextSameMonthDay(date, "03-05"));
//当前时间月日部分和下一个03-05相差天数
System.out.println(DateTimeCalculatorUtil.betweenNextSameMonthDayOfNow("03-05")); //date为准,下一个02-14的日期
System.out.println(DateTimeCalculatorUtil.nextSameMonthDay(date, "02-14"));
//date为准,下一个03-05的日期
System.out.println(DateTimeCalculatorUtil.nextSameMonthDay(date, "03-05"));
//date为准,下一个02-29的日期 ,02-29 只有闰年有。
System.out.println(DateTimeCalculatorUtil.nextSameMonthDay(date, "02-29"));
//当前时间为准,下一个02-29的日期 ,02-29 只有闰年有。
System.out.println(DateTimeCalculatorUtil.nextSameMonthDayOfNow("02-29"));
}

2.3 输出

Sat Feb 29 00:00:00 CST 2020
true
true
true
5
5
Sun Feb 14 00:00:00 CST 2021
Thu Mar 05 00:00:00 CST 2020
Thu Feb 29 00:00:00 CST 2024
Thu Feb 29 00:00:00 CST 2024

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

Java日期时间API系列24-----Jdk8中java.time包中的新的日期时间API类,MonthDay类源码和应用,对比相同月日时间。的更多相关文章

  1. 在WebBrowser中执行javascript脚本的几种方法整理(execScript/InvokeScript/NavigateScript) 附完整源码

    [实例简介] 涵盖了几种常用的 webBrowser执行javascript的方法,详见示例截图以及代码 [实例截图] [核心代码] execScript方式: 1 2 3 4 5 6 7 8 9 1 ...

  2. 在swt中获取jar包中的文件 uri is not hierarchical

    uri is not hierarchical 学习了:http://blog.csdn.net/zdsdiablo/article/details/1519719 在swt中获取jar包中的文件: ...

  3. Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析

    目录 0.前言 1.TemporalAccessor源码 2.Temporal源码 3.TemporalAdjuster源码 4.ChronoLocalDate源码 5.LocalDate源码 6.总 ...

  4. API接口自动化之3 同一个war包中多个接口做自动化测试

    同一个war包中多个接口做自动化测试 一个接口用一个测试类,每个测试用例如下,比如下面是4个测试用例,每个详细的测试用例中含有请求入参,返回体校验,以此来判断每条测试用例是否通过 一个war包中,若含 ...

  5. JDK中的Atomic包中的类及使用

    引言 Java从JDK1.5开始提供了java.util.concurrent.atomic包,方便程序员在多线程环境下,无锁的进行原子操作.原子变量的底层使用了处理器提供的原子指令,但是不同的CPU ...

  6. Andriod项目开发实战(1)——如何在Eclipse中的一个包下建新包

    最开始是想将各个类分门别类地存放在不同的包中,所以想在项目源码包中新建几个不同功能的包eg:utils.model.receiver等,最后的结果应该是下图左边这样的:   很明显建立项目后的架构是上 ...

  7. netty中的发动机--EventLoop及其实现类NioEventLoop的源码分析

    EventLoop 在之前介绍Bootstrap的初始化以及启动过程时,我们多次接触了NioEventLoopGroup这个类,关于这个类的理解,还需要了解netty的线程模型.NioEventLoo ...

  8. 【陪你系列】5 千字长文+ 30 张图解 | 陪你手撕 STL 空间配置器源码

    大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub https://github.com/rongweihe/MoreT ...

  9. Java基础知识强化63:Arrays工具类之方法源码解析

    1. Arrays工具类的sort方法: public static void sort(int[] a): 底层是快速排序,知道就可以了,用空看. 2. Arrays工具类的toString方法底层 ...

  10. SpringtMVC运行流程:@RequestMapping 方法中的 Map、HttpServletRequest等参数信息是如何封装和传递的(源码理解)

    在平时开发SpringtMVC程序时,在Controller的方法上,通常会传入如Map.HttpServletRequest类型的参数,并且可以方便地向里面添加数据.同时,在Jsp中还可以直接使用r ...

随机推荐

  1. 轻量级SpringBoot Office文档在线预览框架

    框架简介 介绍:基于开源项目KkFileView源码提取出,封装成仅用于 Office文档预览(格式转换) 功能的一个通用组件; 原理是把Word转成PDF,PPT转成PDF,Excel转成HTML; ...

  2. 【Spring】使用SpringTest报错 java.lang.NoSuchMethodError

    完整报错信息: "C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -ea -Didea.test.cyclic.buffer.si ...

  3. 【Dos-BatchPrograming】01

    --0. 1.文件后缀的延申 官方教程更推荐使用.cmd作为后缀 .cmd和.bat的区别: http://www.360doc.com/content/12/0810/09/3688062_2293 ...

  4. 寻路数据集 —— PathFinding数据集 —— Moving AI Lab. 实验室

    好几个做pathfinding的论文都是引用这个网站的数据集,不过这个网站的数据集的地图都是 .map 格式,这个类型的格式该如何打开还不知道. Moving AI Lab. 实验室的工作 地址: h ...

  5. 全球最大开源模型Grok-1 —— 马斯克 —— 自然语言大模型

    当前世界上参数最大的开源大语言模型Grok-1,参数权重大小为296GB,即3140亿参数,远远超过了OpenAI的GPT-3.5模型. 该模型采用的3140亿参数的MoE模型,在给定token上的激 ...

  6. Temperature 题解

    前言 题目链接:洛谷:SPOJ:Hydro & bzoj. 题意简述 有一个长度为 \(n\) 的序列,每个位置值的范围为 \([L_i, R_i]\) 内,求原序列可能的最长不降子串长度. ...

  7. SMU Summer 2023 Contest Round 3

    SMU Summer 2023 Contest Round 3 A. Curriculum Vitae 题意就是要求\(1\)后面不能有\(0\)的情况下的子序列最长长度, 也就是求一个最长不下降子序 ...

  8. 【CMake系列】03-cmake 注释、常用指令 message、set、file、for_each、流程控制if

    本文给出了 cmake 中的 一些常用的 指令,可以快速了解,为后面的内容深入 打点基础. 本专栏的详细实践代码全部放在 github 上,欢迎 star !!! 如有问题,欢迎留言.或加群[3927 ...

  9. 华为交换机S5700-52C-EI开启telnet服务

    华为S5700交换机初始化和配置TELNET远程登录方法: 1,交换机开启Telnet服务 <Quidway>system-view #进入系统视图 [Quidway]telnet ser ...

  10. Nuitka打包

    Nuitka打包PySide6/PyQt 本文仅供本人知识总结使用,所以内容会比较浅显,不喜勿喷. 文章目录 Nuitka打包PySide6/PyQt 一.需要C++编译器 二.安装Nuitka 三. ...