如何用Kotlin实现适配任意年份的中国生肖计算器(含月日适配)
中国生肖查询脚本优化方案
核心优化:用数组+索引计算替代固定匹配
首先定义12生肖的数组,顺序对应鼠到猪:
val zodiacs = arrayOf("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪")
中国生肖每12年循环一次,所有鼠年的年份模12结果都是4(比如2020、1996、1984等),所以可以通过以下公式计算年份对应的数组索引:
fun getZodiacIndex(year: Int): Int { val rawIndex = (year - 4) % 12 // 处理年份小于4的情况,确保索引非负 return if (rawIndex < 0) rawIndex + 12 else rawIndex }
这样不管输入哪一年,都能直接通过索引从数组中取出对应生肖,彻底去掉when条件判断。
解决年初生肖判断错误:加入月日校验
中国生肖以农历春节为分界点,公历1-2月出生的人可能属于上一年的生肖。我们需要先判断输入的公历日期是否在当年农历春节之前,若是则将年份减1再计算生肖。
实现日期校验函数
import java.time.LocalDate import java.util.Calendar import java.util.Locale fun isBeforeSpringFestival(date: LocalDate): Boolean { val year = date.year // 使用中国农历日历获取当年春节(正月初一)的公历日期 val chineseCalendar = Calendar.getInstance(Locale.CHINA) chineseCalendar.set(Calendar.YEAR, year) chineseCalendar.set(Calendar.MONTH, Calendar.JANUARY) chineseCalendar.set(Calendar.DAY_OF_MONTH, 1) // 定位到农历正月初一对应的公历日期 while (chineseCalendar.get(Calendar.MONTH) != Calendar.JANUARY || chineseCalendar.get(Calendar.DAY_OF_MONTH) != 1) { chineseCalendar.add(Calendar.DAY_OF_MONTH, 1) } val springFestival = LocalDate.of( chineseCalendar.get(Calendar.YEAR), chineseCalendar.get(Calendar.MONTH) + 1, // Calendar月份从0开始,需+1转成标准月份 chineseCalendar.get(Calendar.DAY_OF_MONTH) ) return date.isBefore(springFestival) }
整合完整查询函数
fun getChineseZodiac(date: LocalDate): String { val zodiacs = arrayOf("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪") var targetYear = date.year // 若日期在春节前,使用上一年份计算生肖 if (isBeforeSpringFestival(date)) { targetYear -= 1 } val index = (targetYear - 4) % 12 val validIndex = if (index < 0) index + 12 else index return zodiacs[validIndex] }
测试示例
fun main() { println("请输入出生日期(格式:yyyy-MM-dd):") val input = readLine() ?: "" val birthDate = runCatching { LocalDate.parse(input) }.getOrNull() ?: run { println("日期格式错误,请重新输入") return } val zodiac = getChineseZodiac(birthDate) println("你的生肖是:$zodiac") }
关键点说明
- 数组索引计算:通过年份与基准值(4)的差值取模12,直接映射到生肖数组,逻辑简洁且支持任意年份。
- 农历春节校验:利用Java的
Calendar类结合中国 locale 获取准确的春节公历日期,避免了硬编码日期带来的误差。 - 边界处理:考虑了年份小于4的极端情况,确保索引始终在数组合法范围内。
内容的提问来源于stack exchange,提问作者India Store
相关产品推荐
相关产品推荐

