0
点赞
收藏
分享

微信扫一扫

高级JAVA开发必备技能:java8 JSR-310判断是否闰年实现,发现原作者的代码可能有问题(JAVA 小虚竹)

做个橙梦 2022-02-23 阅读 24



❤️作者简介:Java领域优质创作者????
❤️技术活,该赏

❤️点赞 ???? 收藏 ,养成习惯


Chronology 判断是否闰年

判断是否闰年是由年表​Chronology​ 提供的,通常情况下,我们使用ISO下的年表,是​IsoChronology​ 。

看下代码实现

@Override
public boolean isLeapYear(long prolepticYear) {
return ((prolepticYear & 3) == 0) && ((prolepticYear % 100) != 0 || (prolepticYear % 400) == 0);
}

好精炼的代码,值得我们研究研究

闰年的基本判定方法:

1、非整百年:能被4整除的为闰年。(如2004年就是闰年,2001年不是闰年)

2、整百年:能被400整除的是闰年。(如2000年是闰年,1900年不是闰年)

((prolepticYear & 3) == 0) && ((prolepticYear % 100) != 0 || (prolepticYear % 400) == 0);

这段代码用了两个条件,这两个条件都符合,才是闰年。


  • (prolepticYear & 3) == 0
  • (prolepticYear % 100) != 0 || (prolepticYear % 400) == 0

(prolepticYear & 3) == 0​ 用了与运算符“&”,其使用规律如下:

两个操作数中位都为1,结果才为1,否则结果为0。

3​ 的二进制是​011​ ,​prolepticYear & 3​ 目的是保留最后2位二进制数,然后判断是否最后两位二进制数等于0。如果等于0,证明能被4整除。闰年一定要满足是4的倍数的条件;

(prolepticYear % 100) != 0 || (prolepticYear % 400) == 0​ 这个就比较好理解了,看是不是100的倍数或者是不是400 倍数。

而且小虚竹发现​java.time.Year#isLeap()​ 用的实现代码逻辑是一样的

public static boolean isLeap(long year) {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
}

即使是巨佬写的代码,也存在代码的复用性问题

上面IsoChronology 是对Chronology接口接口的isLeapYear实现,MinguoChronology等实现类的isLeapYear,互用了IsoChronology的isLeapYear方法。

//MinguoChronology 
public boolean isLeapYear(long prolepticYear) {
return IsoChronology.INSTANCE.isLeapYear(prolepticYear + YEARS_DIFFERENCE);
}

巨佬是有考虑复用的,在MinguoChronology等实现类已经有复用了。

java.time.Year#isLeap()​ 的优先级高,因为它是静态方法。​isoChronology ** 可以引​Year.isLeap**

Year ** 不可以引​Chronology.isLeapYear** 。

博主发现在​IsoChronology ** 的​resolveYMD** 中已经存在了对​Year.isLeap​ 的引用。

高级JAVA开发必备技能:java8 JSR-310判断是否闰年实现,发现原作者的代码可能有问题(JAVA 小虚竹)_jsr-310

有的工具类会为了减少外部类依赖,重新写一次底层方法,避免外部类(或是不在一个包底下)的类依赖,这个已经用了,说不过去​ 。所以代码是存在复用性问题的。

实战

int year = 2020;
System.out.println(Year.isLeap(year));
System.out.println(IsoChronology.INSTANCE.isLeapYear(year));

LocalDate localDate = LocalDate.of(2021,9,7);
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDate.isLeapYear());
System.out.println(localDateTime.toLocalDate().isLeapYear());

高级JAVA开发必备技能:java8 JSR-310判断是否闰年实现,发现原作者的代码可能有问题(JAVA 小虚竹)_jsr-310_02


今天是持续写作的第 10 / 100 天。
可以关注我,点赞我、评论我、收藏我啦。



举报

相关推荐

0 条评论