为什么一月是Java日历中的第0个月?

java.util.Calendar中,一月被定义为第0个月,而不是第1个月。有什么具体的原因吗

我看到很多人对此感到困惑

这只是Java日期/时间API的可怕混乱的一部分。列出它的问题需要很长时间(我肯定我不知道一半的问题)。诚然,处理日期和时间是很棘手的,但无论如何,啊

帮自己一个忙,使用Joda Time,或者可能JSR-310

编辑:至于原因——正如其他答案所指出的,这很可能是由于旧的C API,或者只是一种从0开始的感觉。。。当然,天是从1开始的。我怀疑最初的实现团队之外的任何人是否真的能说明原因,但我再次敦促读者不要太担心为什么会做出错误的决定,而是看看java.util.Calendar中的所有肮脏之处,并找到更好的东西

支持使用基于0的索引的一点是,它使“名称数组”之类的事情变得更容易:

//我“知道”有12个月
String[]monthNames=新字符串[12];//并填充。。。
String name=monthNames[calendar.get(calendar.MONTH)];

当然,当你得到一个13个月的日历时,这就失败了。。。但至少指定的大小是您预期的月数

这不是一个好的原因,但它是一个原因

编辑:作为一种评论,我想问一下我认为日期/日历有什么问题:

  • 令人惊讶的基数(1900为日期的年基数,不推荐的构造函数是这样的;0为两者的月基数)
  • 易变性-使用不可变类型使处理真正有效的值变得更加简单
  • 类型集不足:最好将日期日历作为不同的东西,
    但缺少“本地”值与“分区”值的分离,日期/时间与日期与时间的分离也是如此
  • 这是一个API,它使用神奇的常量而不是清晰命名的方法生成丑陋的代码
  • 一个很难推理的API——所有的业务都是关于什么时候重新计算等等
  • 使用无参数构造函数将默认值设置为“now”,这会导致难以测试代码
  • 始终使用系统本地时区的Date.toString()实现(这让以前的许多堆栈溢出用户感到困惑)

发表评论