之前看到的一个思维题 《生日问题》

通过对话推理,小明和小强最终确定了老师的生日为9月1日。此过程揭示了逻辑思维的重要性。

这是可能的生日情况:

3月4-5-8


6月4-7


9月1-5


12月1-2-8

张老师把月份告诉了小明,把日子告诉了小强,张老师问他们知道他的生日是那一天吗?


    小明说:如果我不知道的话,小强肯定也不知道。


    小强说:本来我也不知道,但是现在我知道了。

 

    小明说:哦,那我也知道了。

 

什么时候小明会这么说呢?小明知道月份,所以他知道这个月份中
没有唯一的号数可以直接判断出生日是什么日子。小强听到小明说的话
后,也知道了小明的意思,因此排除了6月和12月。如果小强知道的号数是5的话,他是
无法说出这句话的,既然他现在知道了说明号数是1、4、8中的一个。后面小明说:那我也知道了。
如果小明知道的月数是3月的话,那么他还是不能确定是3月4号还是8号,但他说他知道了,所以答案就是9月1号

当然可以!以下是一个完整的 Java 方法,用于**根据传入的生日计算当前年龄**。该方法使用了 `java.time` 包中的现代日期 API(推荐方式),准确、安全且支持时区无关的本地日期处理。 ```java import java.time.LocalDate; import java.time.Period; import java.time.format.DateTimeFormatter; public class AgeCalculator { /** * 根据生日计算当前年龄 * @param birthDate 生日日期(LocalDate 类型) * @return 计算出的年龄(整数) */ public static int calculateAge(LocalDate birthDate) { if (birthDate == null) { throw new IllegalArgumentException("生日不能为 null"); } // 获取当前日期(不包含时间与时区) LocalDate currentDate = LocalDate.now(); // 确保生日不晚于当前日期 if (birthDate.isAfter(currentDate)) { throw new IllegalArgumentException("生日不能晚于当前日期"); } // 使用 Period 计算两个日期之间的年、、日差值 return Period.between(birthDate, currentDate).getYears(); } /** * 重载方法:接受字符串格式的生日(如 "1990-05-20")并计算年龄 * @param birthDateString 生日字符串 * @param formatter 日期格式器,默认可使用 DateTimeFormatter.ISO_LOCAL_DATE * @return 年龄 */ public static int calculateAge(String birthDateString, DateTimeFormatter formatter) { if (birthDateString == null || formatter == null) { throw new IllegalArgumentException("生日字符串或格式器不能为 null"); } LocalDate birthDate = LocalDate.parse(birthDateString, formatter); return calculateAge(birthDate); } // 测试方法 public static void main(String[] args) { // 示例1:使用 LocalDate LocalDate birthDate1 = LocalDate.of(1990, 5, 20); System.out.println("出生日期: " + birthDate1 + " → 年龄: " + calculateAge(birthDate1)); // 示例2:使用字符串解析(ISO 格式 yyyy-MM-dd) String birthStr = "2000-12-01"; DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE; System.out.println("出生日期: " + birthStr + " → 年龄: " + calculateAge(birthStr, formatter)); // 示例3:非法输入测试 try { LocalDate futureDate = LocalDate.of(2099, 1, 1); calculateAge(futureDate); } catch (IllegalArgumentException e) { System.out.println("错误: " + e.getMessage()); } } } ``` --- ### ✅ 解释: 1. **`LocalDate.now()`**: - 获取系统当前日期(无时间、无时区),适合用于生日计算; - 比旧的 `Date` 和 `Calendar` 更清晰、线程安全。 2. **`Period.between(start, end).getYears()`**: - 正确计算“完整年数”; - 自动处理是否已过生日问题(例如:如果今年还没过生日,年龄减一); > 示例: > 出生:2000-05-20,今天是 2025-04-05 → 还没过生日 → 年龄 = 24 > 如果是 2025-05-20 或之后 → 年龄 = 25 3. **输入验证**: - 防止 `null` 输入; - 检查生日是否在未来,避免逻辑错误; 4. **字符串解析支持**: - 提供重载方法,允许传入 `"1990-05-20"` 这样的字符串; - 可自定义格式器,比如 `.ofPattern("dd/MM/yyyy")` 来支持 `"20/05/1990"`; --- ### 🔧 扩展建议: 如果你想支持非 ISO 格式的日期,例如 `"20-05-1990"`,可以这样调用: ```java DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); int age = calculateAge("20-05-1990", customFormatter); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值