在java.util。日历中,一月被定义为第0个月,而不是第1个月。这有什么具体原因吗?

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


当前回答

真正的原因

You would think that when we deprecated most of Date and added the new Calendar class, we would have fixed Date's biggest annoyance: the fact that January is month 0. We certainly should have, but unfortunately we didn't. We were afraid that programmers would be confused if Date used zero-based months and Calendar used one-based months. And a few programmers probably would have been. But in hindsight, the fact that Calendar is still zero-based has caused an enormous amount of confusion, and it was probably the biggest single mistake in the Java international API's.

引用自Laura Werner的Java国际日历,链接在底部。

更好的选择:java.time

这可能只是重复其他人所说的,抛弃旧的和设计糟糕的Calendar类,使用java。时间,现代Java日期和时间API。从1月的1到12月的12,月份的编号始终是合理的。

如果您从尚未升级到java的遗留API中获取Calendar。时,要做的第一件事是转换为现代的ZonedDateTime。根据你的需要,你可以从那里做进一步的转换。在大多数情况下,您获得的Calendar对象实际上总是GregorianCalendar子类的一个实例(因为Calendar类本身是抽象的)。demonstreate:

    Calendar oldfashionedCalendarObject = Calendar.getInstance();
    ZonedDateTime zdt
            = ((GregorianCalendar) oldfashionedCalendarObject).toZonedDateTime();
    
    System.out.println(zdt);
    System.out.format("Month is %d or %s%n", zdt.getMonthValue(), zdt.getMonth());

当我刚刚在我的时区运行时输出:

2021 - 03 - 17 - t23:18:47.761 + 01:00[欧洲/哥本哈根] 月是3号或MARCH

链接

Laura Werner编写的Java国际日历 Oracle教程:Date Time解释如何使用java.time。

其他回答

我想说是懒惰。数组从0开始(每个人都知道);一年中的月份是一个数组,这让我相信Sun的一些工程师只是懒得在Java代码中加入这个小细节。

因为所有东西都是从0开始的。这是Java编程的一个基本事实。如果有一件事偏离了这一点,那么就会导致一系列的混乱。让我们不要争论它们的构成和代码。

因为程序员痴迷于基于0的索引。好吧,实际情况要比这复杂一些:当您使用基于0的索引来处理底层逻辑时,它更有意义。但总的来说,我还是会坚持我的第一句话。

除了DannySmurf关于懒惰的回答之外,我还要补充一句,这是为了鼓励您使用常量,例如Calendar.JANUARY。

设置月份为“日历”。MARCH,或者比较,看看它是否== Calendar。比如六月。

Date和Calendar类可以追溯到Java的早期,当时人们还在摸索,它们被广泛认为设计得不是很好。

如果今天用相同的设计创建Calendar,而不是int类型的Calendar。JUNE等等,他们会用枚举。