在 java.util.Calendar
中,一月被定义为第 0 个月,而不是第 1 个月。有什么具体原因吗?
我看到很多人对此感到困惑......
最佳答案
这只是 Java 日期/时间 API 的可怕困惑的一部分。列出它的问题需要很长时间(而且我确信我不知道一半的问题)。诚然,处理日期和时间是很棘手的,但无论如何都是 aaargh。
帮自己一个忙,使用Joda Time相反,或者可能JSR-310 .
编辑:至于原因 - 正如其他答案中所述,这很可能是由于旧的 C API,或者只是从 0 开始的一般感觉......当然,除了那些日子从 1 开始。我怀疑原始实现团队之外的任何人是否真的可以说明原因 - 但我再次敦促读者不要太担心为什么做出了错误的决定,而是要看看整个肮脏的范围在 java.util.Calendar
中找到更好的东西。
赞成使用基于 0 的索引的一点是,它使“名称数组”之类的事情变得更容易:
// I "know" there are 12 months
String[] monthNames = new String[12]; // and populate...
String name = monthNames[calendar.get(Calendar.MONTH)];
当然,一旦你得到一个有 13 个月的日历,这就会失败......但至少指定的大小是你期望的月数。
这不是一个好的理由,但这是一个的理由......
编辑:作为评论,请求一些关于我认为日期/日历有问题的想法:
- 令人惊讶的基数(1900 作为 Date 的年份基数,对于已弃用的构造函数来说是公认的;0 作为两个月份的基数)
- 可变性 - 使用不可变类型可以更加更轻松地处理真正有效的值
- 类型集不足:将
Date
和Calendar
作为不同的东西,这很好, 但是缺少“本地”与“分区”值的分离,日期/时间与日期与时间也是如此 - 一个 API 会导致带有魔法常量的丑陋代码,而不是明确命名的方法
- 一个很难推理的 API - 所有关于何时重新计算事物等的业务
- 使用无参数构造函数默认为“现在”,导致代码难以测试
Date.toString()
实现总是使用系统本地时区(这让很多 Stack Overflow 用户感到困惑)
关于java - 为什么 Java 日历中的 1 月是 0 月?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/344380/