在java.util。日历中,一月被定义为第0个月,而不是第1个月。这有什么具体原因吗?
我看到很多人对此感到困惑……
在java.util。日历中,一月被定义为第0个月,而不是第1个月。这有什么具体原因吗?
我看到很多人对此感到困惑……
当前回答
There has been a lot of answers to this, but I will give my view on the subject anyway. The reason behind this odd behavior, as stated previously, comes from the POSIX C time.h where the months were stored in an int with the range 0-11. To explain why, look at it like this; years and days are considered numbers in spoken language, but months have their own names. So because January is the first month it will be stored as offset 0, the first array element. monthname[JANUARY] would be "January". The first month in the year is the first month array element.
另一方面,由于日期数字没有名称,将它们存储在0-30的int型中会令人困惑,添加大量的day+1指令用于输出,当然,也容易出现很多错误。
也就是说,这种不一致是令人困惑的,特别是在javascript(它也继承了这个“特性”)中,这种脚本语言应该从语言中抽象出来。
因为月份有名称,而月份中的日期没有。
其他回答
真正的原因
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。
可能是因为C的“struct tm”也有同样的功能。
因为语言写作比看起来要难得多,特别是处理时间比大多数人想象的要难得多。关于这个问题的一小部分(在现实中,不是Java),请参阅YouTube视频“时间和时区的问题-计算机爱好者”,网址是https://www.youtube.com/watch?v=-5wpm-gesOY。如果你在困惑中笑掉了头,不要感到惊讶。
基于C的语言在某种程度上复制了C。tm结构(在time.h中定义)有一个整数字段tm_mon,(注释的)范围为0-11。
基于C的语言从索引0开始数组。因此,这对于以tm_mon作为索引输出月份名称数组中的字符串非常方便。
在Java 8中,有一个新的日期/时间API JSR 310,它更加合理。规范负责人与JodaTime的主要作者相同,他们共享许多相似的概念和模式。