解析计算月份天数的Kotlin代码原理及相关算法疑问
解析计算月份最后一天的Kotlin代码
先把原代码贴出来:
private fun lastDayInMonth(month: Int, year: Int): Int { return if (month != 2) { 31 - (month - 1) % 7 % 2 } else { if (year and 3 == 0 && (year % 25 != 0 || year and 15 == 0)) { 29 } else { 28 } } }
一、工作原理与实现逻辑
1. 非2月的月份天数计算
除2月外,其他月份的天数靠31 - (month - 1) % 7 % 2计算,拆解开看:
month - 1:把1-12月转成0-11的索引,方便后续分组计算(month-1) %7:将月份按7个一组划分,结果范围是0-6- 再对2取余:得到0或1,用来区分大月(31天)和小月(30天)
- 用31减去这个结果:得0就是31天,得1就是30天
对应实际月份的结果完全符合公历规律:1、3、5、7、8、10、12月都是31天,4、6、9、11月都是30天。
2. 2月的闰年判断
2月的天数由闰年规则决定,代码用位运算+取余实现了标准闰年逻辑:year and 3 == 0 && (year % 25 != 0 || year and 15 == 0)
翻译过来就是:
year and 3 == 0:等价于「年份能被4整除」(3的二进制是11,和年份按位与结果为0,说明年份是4的倍数)year %25 !=0:排除能被100整除的年份(能被100整除的数必然能被25整除)year and15 ==0:等价于「年份能被16整除」,而同时被25和16整除的数,就是能被400整除的数(16和25互质,最小公倍数是400)
合起来就是标准闰年规则:能被4整除但不能被100整除,或者能被400整除。满足条件2月有29天,否则28天。
二、算法名称与作者
这段算法没有广泛公认的特定名称,它是利用公历月份天数的固定规律,加上闰年规则的位运算优化实现的。这类位运算优化的日期计算,大多是开发者为了减少日期库依赖、简化分支逻辑设计的小技巧。原代码来自Gist用户slaviboy,但核心逻辑属于常见的日期计算优化思路,没有特定的知名作者或官方命名。
内容的提问来源于stack exchange,提问作者me.at.coding
相关产品推荐
相关产品推荐

