You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:33:14