my dog learned polymorphism
The moose likes Java in General and the fly likes Calendar.MONTH iz zero based, by YEAR and DAY_OF_MONTH are not Big Moose Saloon
  Search | Java FAQ | Recent Topics
Register / Login
JavaRanch » Java Forums » Java » Java in General
Reply Bookmark "Calendar.MONTH iz zero based, by YEAR and DAY_OF_MONTH are not" Watch "Calendar.MONTH iz zero based, by YEAR and DAY_OF_MONTH are not" New topic
Author

Calendar.MONTH iz zero based, by YEAR and DAY_OF_MONTH are not

Warren Goldman
Greenhorn

Joined: Jan 26, 2010
Posts: 3
Why isn't Calendars DAY_OF_MONTH and YEAR zero based, like the month is?
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 5791
    
    5

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
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
The usual algorithm is to add 1.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 2770
    
    2
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
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.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 5791
    
    5

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.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 5791
    
    5

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
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
I agree with your last post. Lots of stuff in Calendar smells funny. And a modern design with enums would be much preferred.
Warren Goldman
Greenhorn

Joined: Jan 26, 2010
Posts: 3
Great info, thanks!
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 5791
    
    5

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.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 5791
    
    5

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.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 3786
    
    1

Jeff Verdegan wrote:
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!).
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19216

That's the technique I always use.

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.


SCJP 1.4 - SCJP 6 - SCWCD 5
How To Ask Questions How To Answer Questions
Tim Moores
Rancher

Joined: Sep 21, 2011
Posts: 2407
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
Good point - I had forgotten how much wasn't in 1.0.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 16479
    
    2

Tim Moores wrote:With the benefit of hindsight, even in 1995, a date/time API with no concept of timezones was ... amazing.


And their consideration of the imminent Y2K problem in 1995 was hardly what you would call forward-looking:
The API docs for Date wrote:A year y is represented by the integer y - 1900

 
I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to run our stuff on 16 servers instead of 3.
 
subject: Calendar.MONTH iz zero based, by YEAR and DAY_OF_MONTH are not
 
Similar Threads
Simple Calendar
Bug in Javascript Date object?
Dates (using them, not getting them)
how to quickly get current year/month ?
Array Index Out of Bound Exception