Warren Goldman wrote:Why isn't Calendars DAY_OF_MONTH and YEAR zero based, like the month is?
Because DAY_OF_MONTH and YEAR are meant to represent actual numerical values. MONTH, on the other hand, is merely meant as an index to a name lookup.
We're expected to use the number values from DAY_OF_MONTH and YEAR. We're not expected to use the number values of MONTH. If the next release of Java changes MONTH to be -5 based, and that breaks your code, then your code had a bug in the first place--it relied on an implementation detail. If you're doing something like cal.get(Calendar.MONTH) + 1 /* +1 to account for zero-base */ then you're using it wrong.
Warren Goldman
Greenhorn
Joined: Jan 26, 2010
Posts: 3
posted
0
Why does it exist then, how is it to be used? If it is used to simply pass along to another api provided in calendar, I would suggest Calendar has the bug.
Secondly, how should I get the true calendar number (i.e. January should be 1)?
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
1
The usual algorithm is to add 1.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
Hm, having read Jeff's response now, I don't agree. The values of those constants are fixed in the JavaDoc, see here. The fact that it starts from 0 rather than 1 is also documented at Calendar.MONTH. It's not something Sun or Oracle has any business changing at this point, short of moving to a different API entirely.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
1
As for why it is this way, the Calendar API is the classic Java example of an API that was designed too quickly, during the rush to get the initial public release of Java out. One suspects hallucinogens may have been involved as well. It's not pretty, and it's not consistent. Nonetheless it is capable of calculating a lot of things that would be a pain in the butt to calculate ourselves. We just to understand its idiosyncracies.
Warren Goldman wrote:Why does it exist then, how is it to be used?
Set the month to Calendar.MARCH, or compare to see if it == Calendar.JUNE, for example.
The Date and Calendar classes date back to the very early days of Java, when folks were still figuring things out, and they are widely regarded as not very well designed.
If Calendar were created today with the same design, rather than ints for Calendar.JUNE, etc., they'd use enums.
Mike Simmons wrote:Hm, having read Jeff's response now, I don't agree. The values of those constants are fixed in the JavaDoc, see here. The fact that it starts from 0 rather than 1 is also documented at Calendar.MONTH. It's not something Sun or Oracle has any business changing at this point, short of moving to a different API entirely.
True, it's publicly documented and therefore part of the public API, but I consider that in itself to be a bug. If it was intended to be used numerically, then the publicly visible numeric values should have been the expected 1 for Jan., 2 for Feb., etc. To publicly document that it's zero-based and then leave the user to have to add 1 (or subtract 1, depending on which direction you're going) is just icky bad.
So, while I guess it's not technically a bug if your code relies on those values (being that they're documented and all), I would still say it shows rather poor judgement to do so. It just smells funny.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
Jeff Verdegan wrote:If you're doing something like cal.get(Calendar.MONTH) + 1 /* +1 to account for zero-base */ then you're using it wrong.
Mike Simmons wrote:The usual algorithm is to add 1.
I will revise my answer in one important respect - the usual method to use is to rely on other classes and methods, most commonly DateFormat / SimpleDateFormat, to convert a date / time to whatever display format you want. Including using an ordinal number for the month, if that's desired.
But if for some reason you find it more convenient to just add 1, that works too.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
I agree with your last post. Lots of stuff in Calendar smells funny. And a modern design with enums would be much preferred.
Also note that there's a 3rd party library (free, I think), called Joda, that's supposed to be a cleaner design than the core API date/time handling stuff, have lots of utilities for common operations, and include stuff like durations and, if I'm not mistaken, dateless and TZ-less times and timeless dates, which are not provided by the core API.
An adaptation of Joda was supposed to be included in Java 7, but didn't make it in. Supposedly they're going to try again with Java 8.
Mike Simmons wrote:
But if for some reason you find it more convenient to just add 1, that works too.
Yeah, it will work, and it will probably always work, but I just don't like doing it. To me it's relying on a hack--a documented hack, but still a hack--and it leaves me feeling like I need a shower.
Mike Simmons wrote:
But if for some reason you find it more convenient to just add 1, that works too.
Yeah, it will work, and it will probably always work, but I just don't like doing it. To me it's relying on a hack--a documented hack, but still a hack--and it leaves me feeling like I need a shower.
If you want it a bit more robust, and don't mind extra verbosity, you can always add 1 - Calendar.JANUARY. That's safe (until they change the month constants to no longer be sequential!).
Anyway, what I find more confusing is why Calendar.DAY_OF_WEEK is 1 based instead of 0 based. I would expect both Calendar.MONTH and Calendar.DAY_OF_WEEK to use the same base. Of course it doesn't matter if you use the correct technique (weekday - Calendar.SUNDAY to make it 0 based), but it still annoys me a little bit.
Mike Simmons wrote:As for why it is this way, the Calendar API is the classic Java example of an API that was designed too quickly, during the rush to get the initial public release of Java out.
Just nitpicking here, but the Calendar class wasn't in Java 1.0 - it was introduced in Java 1.1. So it wasn't the initial rush to get 1.0 out the door, but the rush to fix all the big holes that were left in the API in the rush to get 1.0 out the door :-) With the benefit of hindsight, even in 1995, a date/time API with no concept of timezones was ... amazing.
Mike Simmons
Ranch Hand
Joined: Mar 05, 2008
Posts: 2770
2
posted
0
Good point - I had forgotten how much wasn't in 1.0.