Question

Okay so this one is stumping me. I have the following code which attempts to create this string:

OUTPUT: 52. 2012 (24 Dec to 30 Dec)

Which is the start and end of the 52nd week of the year 2012, with Monday being the first day of the week.

private Date getDateObject() {
    Calendar cld = Calendar.getInstance();
    cld.set(Calendar.YEAR, year);
    cld.set(Calendar.WEEK_OF_YEAR, week);
    cld.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    return cld.getTime();
}

private Date getEndDateObject() {
    Calendar cld = Calendar.getInstance();

    if (week < 52) {
        cld.set(Calendar.YEAR, year);
        cld.set(Calendar.WEEK_OF_YEAR, week + 1);
    } else {
        cld.set(Calendar.YEAR, year + 1);
        cld.set(Calendar.WEEK_OF_YEAR, 1);
    }

    cld.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
    return cld.getTime();
}

public String getDateRangeString() {
    String pattern = "d MMM";
    SimpleDateFormat formatter = new SimpleDateFormat(pattern); 

    Date startDate = getDateObject();
    Date endDate = getEndDateObject();

    String startDateFormatted = formatter.format(startDate);
    String endDateFormatted = formatter.format(endDate);

    String dateString = "" + this.week + ". " + this.year + " (" + startDateFormatted + " to " + endDateFormatted + ")";
    return dateString;
}

The function getDateRangeString when used on the object with YEAR = 2012 and WEEK = 52 gives the following output on the following devices:

  • Nexus S - 4.1
  • Emulator 4.1
  • Emulator 4.2

OUTPUT: 52. 2012 (24 Dec to 30 Dec)

Which is correct!

But on the Nexus 7 running 4.2.1 I get:

OUTPUT: 52. 2012 (24 Dec to 6 Jan)

WTF!!?!?

All devices are set to Australian EST +10 and have correct time / date right now. I don't think this has anything to do with the missing December month in 4.2 which should be fixed in 4.2.1 anyway.

When I debug it, the calendar says it has all the correct values. Then out comes 6th of Jan?

I mean its a weird one coz the 31st of December is like a 53rd week or something? I dunno, I just don't get why this device is in any way different.

Was it helpful?

Solution

Okay, so firstly thanks to Jon Skeet for the suggestion of adding 6 days to get the end of the week to avoid all sorts of problems. That is definately the way to go.

So for future reference, avoid Java Calendar / Date its foobared. BUT I got my code working on every device / platform by accident.

Here is my modified code:

private Date getDateObject() {
    Calendar cld = Calendar.getInstance();
    cld.set(Calendar.YEAR, year);
    cld.set(Calendar.WEEK_OF_YEAR, week);
    cld.get(Calendar.DAY_OF_WEEK); // WARNING this line is required to make the code work. Might have something to do with an inner function called complete which gets called on get.
    cld.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    return cld.getTime();
}

private Date getEndDateObject() {
    Date endDateObject = getDateObject();
    long timeMilliseconds = endDateObject.getTime();
    long sixDaysMilliseconds = 60 * 60 * 24 * 6 * 1000;
    endDateObject.setTime(timeMilliseconds + sixDaysMilliseconds);
    return endDateObject;
}

Pay special attention to the line

    cld.get(Calendar.DAY_OF_WEEK);

If anyone can explain WHY a getter is effecting the output of the calendar then bonus points to them. But im sorry WTF.... the only reason why I stumbled upon this was I had a get in my Log.i and then the code was working on all devices. Then when I went to clean it up and remove all my debugging and commented code it stopped working again. So I eventually got it down to the getter. If I comment that line out the date that comes back is wrong and whats worse..... every call to the calendar returns the same date / time even though the logging shows they are using different years and weeks..... so in short as suggested, dont use Java Date if possible.

However this still doesnt explain why the Nexus 7 on 4.2.1 returns a different date for the end week if I used my older code. One could possibly make the assumption that there is a difference between my 4.2 Emulator and the Nexus 7 4.2.1 but it seems unlikely.

Never the less, using the 6 day addition method seems the safest and works across the board.

Next time I will use Joda Time but I don't have time to work out how to use it right now.

Thanks to all who helped, this is still a weird mystery in two ways.

  • Why does the getter change the output of the Calendar function? My guess is its something to do with the complete method it claims to internally call. But I can't call complete my self even though its mentioned in the docs.

  • Why does the nexus 7 4.2.1 get a different week than all my other devices / emulators, when the calendar function is fed the exact same parameters.

Weird.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top