Search code examples
javaandroidcalendargregorian-calendar

Calendar.clone() Incorrectly copying milliseconds


It doesn't seem that this question has come up before, so I'll ask it here: Is the expectation with the "shallow" copying of a Calendar via Calendar.clone() that the milliseconds stored become invalid?

I ask because the following chunk of code is failing:

public boolean someFunc(Calendar prevTime, Calendar proposal) {
    int submissionMinuteThreshold = 30;
    boolean isAfterMinTime;
    ...
    Calendar min = (GregorianCalendar) prevTime.clone();
    Log.i("PROJ", "1. Proposed time = " + proposal.getTimeInMillis() + ", min time = " + min.getTimeInMillis());
    min.add(Calendar.MINUTE, submissionMinuteThreshold);
    Log.i("PROJ", "2. Proposed time = " + proposal.getTimeInMillis() + ", min time = " + min.getTimeInMillis());
    isAfterMinTime = proposal.after(min); // returns true even though min is 29 minutes later

I've experimented with the following settings: proposal = 10:34 AM on 2014-10-25 prevTime = 10:33 AM on 2014-10-25

Log output is shown below:

  1. Proposed time = 1414247640000, min time = -61180824420000
  2. Proposed time = 1414247640000, min time = -61180822620000

After looking through the fields of min in the debugger, I see that add correctly sets the hour to 11, minutes to 03, and date to 2014-10-25, so it seems that add works correctly. However, when the comparison is performed, the milliseconds set in min are completely wrong, and that's what after (in the Calendar class) uses for a comparison.

As can be seen in the log output, the root of the problem with the milliseconds stored seems to begin with Calendar min = (GregorianCalendar) prevTime.clone(). Is there some other copy method that I should use so as to ensure valid comparisons later?


Solution

  • The problem was an incorrect initialization of prevTime, as suggested by prettyvoid.