Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Calendar.MONTH returns 2 its March now




On Mar 24, 2005, at 7:50 PM, Greg Guerin wrote:

Glen Ezkovich wrote:

Come on Greg. This is exactly my point. Why are you adding 1 to
Calendar.February in the first place? Are you trying to have bar ==
Calendar.MARCH? If you are, you just hosed yourself by assuming the value
of FEBRUARY would not change.

There are actually two distinct points here, which you seem to be conflating.


Point 1 is the proper use of predefined constants in source, such as
FEBRUARY. Point 2 is whether a predefined constant can be changed in the
future without breaking existing compiled code, i.e. binary compatibility.
They are related issues, but not at all the same.


My point is that you cannot do what you propose, i.e. change the literal
constant value of FEBRUARY in the future. At least not without breaking
binary compatibility.


This would be impossible to change whether or not any code anywhere
performs arithmetic or any operation at all on the value of FEBRUARY.
Something as apparently simple as equality via == would break if the values
were changed. This happens because the literal value at the time the
referring class was compiled is in-lined into the referring class. So if
you changed Calendar.FEBRUARY and didn't recompile all referring classes,
those referring classes would break.


All this happens irrespective of anything I do with the int value of
FEBRUARY. If I just refer to the value at all, it's compiled inline: every
time. Once that happens in any referring class anywhere, the value can't
be changed without breaking binary compatibility.

Right. No argument here. If you change the value of FEBRUARY you need to recompile all code that used it. This is what makes it highly unlikely that Sun would ever do this.


I did not purpose that the value of FEBRUARY be changed. I just suggested that it is possible that a class's implementation may change over time. You should do you best not to depend on the values of constants. In fact you should do your best not use primitive or String literals for public constants.

By treating FEBRUARY as you would any other
int, you've screwed up. FEBRUARY represents the month February not 1.

The primitive int type exhibits certain characteristics like "order" and
"successor". That is, ints can be ordered, for all int values, and any int
value has a successor int value, for all values assignable or comparable to
ints. (A successor is not necessarily higher in magnitude, i.e. "greater
than", but that's a separate question.)


Months also exhibit "order" and "successor" characteristics. So knowing
that FEBRUARY is defined as the int primitive type, why is it such a
problem if the ordering of months and the notion of "successor to month"
map to the expression of those characteristics by ints? That is, why is it
so strange for "successor to FEBRUARY" to be "successor to int value
expressed by FEBRUARY" or FEBRUARY+1?


Especially if the docs say that, which they do.

The docs are pretty clear that JANUARY is 0, FEBRUARY is 1, and so on.
Hence, there is a very clear order and successor nature to the defined
month names.  (Sucessor breaks down after UNDECIMBER, which is also a
separate issue.)

The doc for: public final static int JANUARY /** * Value of the <code>MONTH</code> field indicating the * first month of the year. */

Are you talking about the documentation for the Date class? It has no constants. Of course Calendar points to the values but I'm not sure why. If they were important don't you think they would be on the same page?


And let's not forget that the type of FEBRUARY is the primitive type int.
That's a type, hard and fast. If it were something else, reference or
primitive, then conclusions about order and successor might not be so easy
to infer, but only in the absence of documentation (and there is no absence
of documentation, so the hypothetical point is moot).


If FEBRUARY were a Month type of some kind, then there aren't any specific
rules about ordering or successor, because no reference type implicitly has
such relationships. So you'd have to define ordering and successor methods
and relationships in the definition of the class, if that mattered. If it
didn't matter, or if you wanted to explicitly NOT define order or
successor, then leave those operations out.

Right.



To my
mind the error is that FEBRUARY is of type int, The whole point is don't
assume anything about the values of constants other then what is explicitly
documented.

But the Calendar values *ARE* explicitly documented, so your whole argument
about assumptions made in the absence of documentation just doesn't fly.
Op. cit.:
<http://lists.apple.com/archives/java-dev/2005/Mar/msg00593.html>


Explicit enough?


No. That is the documentation for the class Date. That is an API and not inherent to the language. If you'd like me to just accept this as part of the Java language I won't. I will accept that that is the way the java.util.Date class does things. But remember Date has no constants. Take a look at the current documentation for Date. All methods that deal with days, months, years, hours, etc. are depreciated. If people would like to use the Date class's documentation for its depreciated methods as gospel, so be it.



The fields are there to use in the invocation of the classes
methods, set(Calendar.MONTH, Calendar.FEBRUARY), etc. and to compare the
equality of one month to another.

And the documentation also specifically says that the int values have
ordering and successor characteristics identical to the usual int behavior.
So FEBRUARY+1 is the successor to FEBRUARY, i.e. MARCH. Guaranteed.

I yield. I am not going to argue this point any more. Based on the documentation I can't win.




But the point remains it is a dangerous practice to assume the values of
constants will remain the same over time.

Not true. Constants (defined as compile-time static final literals) MUST
remain the same over time, or code breaks because binary compatibility is
lost.

You are of course, right. You have to assume this in order to use literal constants at all. Unfortunately, I've been burned before.



While it *IS* true that you cannot assume that named constant values have
any particular value, ordering, successor-ship, relationship, etc., you CAN
assume that the values won't change, if binary compatibility is maintained.
It is a consequence of the nature of binary compatibility.


Of course, if you toss out binary compatibility, then your existing
compiled code can break when things change in the future.  Duh.  That's
what breaking binary compatibility means.


This is depending on the
implementation and not the API of a class, thus defeating the purpose of
separating the two.

If named public static final constants are in the public API of the class,
then those values are part of the public API. Therefore, they can't change
in the future, any more than you can change a public method's name or
arg-types or return-type and not have existing code break in the future.



Calendar is an abstract class.

Just not *THAT* abstract.

Its an abstract class. It just has an unimaginative view of what types of calendars can be dreamed up or it would be *MORE* abstract. ;-)




Suppose it were
extended to model a calendar in which JANUARY were not the first month,
DECEMBER was. DECEMBER < JANUARY should be true.

Not possible for Calendar. The nature of how the constants were defined,
as static final ints, absolutely prevents that from happening.



But Calendar.DECEMBER <
Calendar.JANUARY is false. We would want all Calendar instances to be able
to work correctly.

You may want that, but it would be impossible to achieve, if binary
compatibility is also to be retained. You just can't get there from here.


If Calendar had a successor() or predecessor() method, then that's a
different question.


While this example may appear artificial with respect
to Calendar, Its quite common in other domains.

That may be so in other domains. It might even have been possible when
Calendar was being designed. As it now stands, it's impossible to achieve.



Hopefully, you are not
working on mission critical or life sustaining/threatening applications.

It's a side issue, but the Java license does not permit Java to be used in
such applications. See the license details. (May have changed over time,
but it was certainly forbidden in early Java licenses.)



There are right ways and wrongs way to do things. Sometimes the wrong way
is good enough for the moment. Its also the cause of bugs down the road.
Your call.

And sometimes you have to accept what is. Calendar is what it is. You can
argue it should have been something else, but it isn't something else, it
is what is.

I do and it is.


That doesn't mean you can't define another class that's more in line with
the something else you think Calendar should have been.

I have and believe it or not it uses GregorianCalendar to perform some of its work.



But since Calendar has public static final ints in its public API that
define named months, there are some things that are absolutely guaranteed
for those values, for Calendar to retain binary compatibility. That the
literal numeric values (i.e. the bit-patterns) won't change in the future
is one of those guarantees. This must be so regadless of whether you do
arithmetic or ordering comparisons on the values or not. If the
bit-patterns change, code will break.

OK


I think I understand your points about abstractions and assuming too much
about constant values. But we're talking about the concrete Calendar class
here, and its public API expressed as methods and constant fields. Not to
be redundant, but that public API is public, so Sun can't change it without
breaking binary compatibility. That's in the nature of a public API.

But the values of the constants are not part of the API.


If you're talking about how to design a different Calendar-like class, or
even a class that has nothing at all to do with calendars, and then how to
express certain relationships (e.g. order and successor-ship) without
relying on primitive-type relationships, that's a different kettle of fish
suitable for a different list.


Yes and I'm not.

Maybe I was too wide ranging in my responses to this issue and used hypothetical examples that were highly unlikely to come to pass without stressing their hypothetical nature. The point I wanted to make was pretty simple. Sorry I was unsuccessful. I answered these posts in haste and it obviously shows.




Glen Ezkovich HardBop Consulting glen at hard-bop.com



A Proverb for Paranoids:
"If they can get you asking the wrong questions, they don't have to worry about answers."
- Thomas Pynchon Gravity's Rainbow


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden

This email sent to email@hidden
References: 
 >Re: Calendar.MONTH returns 2 its March now (From: Greg Guerin <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.