問題描述
在 java.util.Calendar
中,一月被定義為第 0 個月,而不是第 1 個月.有什么具體原因嗎?
In java.util.Calendar
, January is defined as month 0, not month 1. Is there any specific reason to that ?
我看到很多人對此感到困惑......
I have seen many people getting confused about that...
推薦答案
這只是 Java 日期/時間 API 的可怕混亂的一部分.列出它的問題需要很長時間(而且我確信我不知道一半的問題).誠然,處理日期和時間是很棘手的,但無論如何都是 aaargh.
It's just part of the horrendous mess which is the Java date/time API. Listing what's wrong with it would take a very long time (and I'm sure I don't know half of the problems). Admittedly working with dates and times is tricky, but aaargh anyway.
幫自己一個忙,使用 Joda Time 代替,或者可能使用 JSR-310.
Do yourself a favour and use Joda Time instead, or possibly JSR-310.
至于原因 - 正如其他答案中所述,這很可能是由于舊的 C API,或者只是從 0 開始的一般感覺......當然,除了那些日子從 1 開始.我懷疑原始實施團隊之外的任何人是否真的可以說明原因 - 但我再次敦促讀者不要太擔心為什么做出了錯誤的決定,而是要看看整個骯臟的范圍在 java.util.Calendar
中找到更好的東西.
As for the reasons why - as noted in other answers, it could well be due to old C APIs, or just a general feeling of starting everything from 0... except that days start with 1, of course. I doubt whether anyone outside the original implementation team could really state reasons - but again, I'd urge readers not to worry so much about why bad decisions were taken, as to look at the whole gamut of nastiness in java.util.Calendar
and find something better.
贊成使用基于 0 的索引的一點是,它使名稱數組"之類的事情變得更容易:
One point which is in favour of using 0-based indexes is that it makes things like "arrays of names" easier:
// I "know" there are 12 months
String[] monthNames = new String[12]; // and populate...
String name = monthNames[calendar.get(Calendar.MONTH)];
當然,一旦你得到一個有 13 個月的日歷,這就會失敗......但至少指定的大小是你期望的月數.
Of course, this fails as soon as you get a calendar with 13 months... but at least the size specified is the number of months you expect.
這不是一個好的理由,但這是一個的理由......
This isn't a good reason, but it's a reason...
作為評論,請求一些關于我認為日期/日歷有問題的想法:
As a comment sort of requests some ideas about what I think is wrong with Date/Calendar:
- 令人驚訝的基數(1900 作為 Date 的年份基數,對于已棄用的構造函數來說是公認的;0 作為兩個月份的基數)
- 可變性 - 使用不可變類型可以更加更輕松地處理真正有效的值
- 類型集不足:將
Date
和Calendar
作為不同的東西,這很好,但是缺少本地"與分區"值的分離,日期/時間與日期與時間也是如此 - 一個 API 會導致帶有魔法常量的丑陋代碼,而不是明確命名的方法
- 一個很難推理的 API - 所有關于何時重新計算事物等的業務
- 使用無參數構造函數默認為現在",導致代碼難以測試
Date.toString()
實現總是使用系統本地時區(這讓很多 Stack Overflow 用戶感到困惑)
- Surprising bases (1900 as the year base in Date, admittedly for deprecated constructors; 0 as the month base in both)
- Mutability - using immutable types makes it much simpler to work with what are really effectively values
- An insufficient set of types: it's nice to have
Date
andCalendar
as different things, but the separation of "local" vs "zoned" values is missing, as is date/time vs date vs time - An API which leads to ugly code with magic constants, instead of clearly named methods
- An API which is very hard to reason about - all the business about when things are recomputed etc
- The use of parameterless constructors to default to "now", which leads to hard-to-test code
- The
Date.toString()
implementation which always uses the system local time zone (that's confused many Stack Overflow users before now)
這篇關于為什么 Java 日歷中的 1 月是 0 月?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!