views:

1888

answers:

2

I want to make calendar view in order to support touch interaction. So I'd like to build new custom calendar view. I tried to make mapping function between view offset and real date value.

Here is my idea: If I can compute the number of weeks since base date(in my case, 1989-12-31), it is easy to know offset. HEIGHT_FOR_WEEK * NUM_OF_WEEK is very simple computation to know exact offset.

My problem is this: First I got milliseconds value from base date. And I set the milliseconds to another calendar object. I expected same date from that object. But actually it was different date.

mBaseDateInMillis = mBaseDate.getTimeInMillis();
mAnotherDate.setTimeInMillis(mBaseDateInMillis);
/* I expect mBaseDate == mAnotherDate.
 * but it was different.
 */

Here is my code:

public class CalendarCoordinate {
    public static final long ONEWEEK_IN_MILLISECONDS = 60 * 60 * 24 * 7 * 1000;
    public Calendar mBaseDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    public long mBaseDateInMillis = 0;
    public Calendar mDate = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    public int  mWeekHeight = 30;

    /**
     * CTOR
     */
    public CalendarCoordinate() {
        /* Base date is 1989-12-31 0, 0, 0
         * It was Sunday and offset 0 will be mapped onto this day.
         */
        mBaseDate.set(Calendar.MILLISECOND, 0);
        mBaseDate.set(1989, 12, 31, 0, 0, 0);
        mBaseDateInMillis = mBaseDate.getTimeInMillis();
        Log.v(TAG, "BaseDate:" + mBaseDate.toString());
    }

    /**
     * Compute DATE from Y-Offset
     * @param yOffset
     * @return
     */
     public Calendar dateFromYOffset(int yOffset) {
        long nthWeeks = yOffset / mWeekHeight;
        long millsSinceBaseDate = nthWeeks * ONEWEEK_IN_MILLISECONDS;
        mDate.clear();
        mDate.set(Calendar.MILLISECOND, 0);
        mDate.setTimeInMillis(mBaseDateInMillis + millsSinceBaseDate);

        /* We SHOULD call to update mDate internal data structure. 
         * Java is really strange for this thing
         **/
        mDate.getTimeInMillis();
        return mDate;
    }

    /**
     * Compute Y-Offset from DATE
     * @param date
     * @return
     */
    public long yOffsetFromDate(Calendar cal) {
        long mills = cal.getTimeInMillis();
        long nthWeeks = (mills - mBaseDateInMillis)/ONEWEEK_IN_MILLISECONDS;
        return nthWeeks * mWeekHeight;
    }
}

Anybody can help me? I'm not a good Java programmer.

+2  A: 

This statement confuses me:

/* I expect mBaseDate == mAnotherDate.
 * but it was different.
 */

Are you actually trying to check for equality by doing the comparison: if (mBaseDate == mAnotherDate) { System.out.println("They are the same"); }

If so, your issue is that you are misunderstanding how the "==" operator works in Java. It compares references, rather than comparing the underlying object data, and since these are different objects (with the same values) that will always be false. For a lot more details, see the Java Notes on comparison operators.

Also, these lines look really suspicious to me:

/* We SHOULD call to update mDate internal data structure. 
* Java is really strange for this thing
**/
mDate.getTimeInMillis();

I would really be surprised if Android had a bug requiring you to do this, but I guess anything is possible. What kind of problems do you have without this call?

jsight
A: 

This is because you need to use the "equals" method to compare different objects. Using operator "==" will tell you if the objects are identical (do they reside in the exact same memory location), while the "equals" comparison function will tell you if the two objects are logically equivalent.

Michael Aaron Safyan