Проблема с датой WEEK_OF_YEAR календаря Android Java на Nexus 7 4.2

Хорошо, так что это ставит меня в тупик. У меня есть следующий код, который пытается создать эту строку:

ВЫВОД: 52. 2012 г. (с 24 декабря по 30 декабря)

Что является началом и концом 52-й недели 2012 года, причем понедельник является первым днем ​​недели.

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;
}

Функция getDateRangeString при использовании для объекта с YEAR = 2012 и WEEK = 52 дает следующие выходные данные на следующих устройствах:

  • Нексус С – 4.1
  • Эмулятор 4.1
  • Эмулятор 4.2

ВЫВОД: 52. 2012 г. (с 24 декабря по 30 декабря)

Что правильно!

Но на Nexus 7 под управлением 4.2.1 я получаю:

ВЫВОД: 52. 2012 (24 декабря — 6 января)

ВТФ!!!?!?

Все устройства настроены на австралийский EST +10 и имеют правильное время / дату прямо сейчас. Я не думаю, что это имеет какое-то отношение к отсутствующему декабрьскому месяцу в 4.2, который в любом случае должен быть исправлен в 4.2.1.

Когда я отлаживаю его, календарь говорит, что у него все правильные значения. Тогда выходит 6 января?

Я имею в виду, что это странно, потому что 31 декабря похоже на 53-ю неделю или что-то в этом роде? Я не знаю, я просто не понимаю, почему это устройство чем-то отличается.


person Madhava Jay    schedule 18.01.2013    source источник
comment
Календарь API очень сбивает с толку, вместо этого я рекомендую вам использовать Joda-Time.   -  person dd619    schedule 18.01.2013
comment
Ваш код на данный момент несколько сбивает с толку - я подозреваю, что там есть тонкие скрытые ошибки. Непонятно, почему вы просто не добавляете 6 дней к дате начала (в то время как все еще в Calendar, чтобы избежать проблем с летним временем). Вы можете посмотреть на Calendar.getMinimalDaysInFirstWeek как на работающих, так и на нерабочих устройствах, чтобы увидеть, отличается ли это, чтобы объяснить разные выходные данные.   -  person Jon Skeet    schedule 18.01.2013


Ответы (1)


Итак, во-первых, спасибо Джону Скит за предложение добавить 6 дней, чтобы получить конец недели, чтобы избежать всевозможных проблем. Это определенно путь.

Так что для дальнейшего использования избегайте использования Java Calendar/Date. НО мой код случайно заработал на каждом устройстве/платформе.

Вот мой модифицированный код:

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;
}

Обратите особое внимание на строку

    cld.get(Calendar.DAY_OF_WEEK);

Если кто-нибудь может объяснить, ПОЧЕМУ геттер влияет на вывод календаря, то бонусные баллы им. Но мне жаль, WTF .... единственная причина, по которой я наткнулся на это, заключалась в том, что у меня был вход в мой Log.i, а затем код работал на всех устройствах. Затем, когда я пошел, чтобы очистить его и удалить весь мой код отладки и комментариев, он снова перестал работать. Так что в конце концов я добрался до геттера. Если я прокомментирую эту строку, возвращаемая дата будет неправильной, и что еще хуже..... каждый вызов календаря возвращает одну и ту же дату/время, хотя журнал показывает, что они используют разные годы и недели..... так что короче говоря, как было предложено, не используйте Java Date, если это возможно.

Однако это все еще не объясняет, почему Nexus 7 на 4.2.1 возвращает другую дату для последней недели, если я использовал свой старый код. Можно было бы предположить, что между моим эмулятором 4.2 и Nexus 7 4.2.1 есть разница, но это маловероятно.

Тем не менее, использование 6-дневного метода добавления кажется самым безопасным и работает повсеместно.

В следующий раз я воспользуюсь Joda Time, но сейчас у меня нет времени разбираться, как им пользоваться.

Спасибо всем, кто помог, это все еще странная загадка в двух смыслах.

  • Почему геттер изменяет вывод функции календаря? Я предполагаю, что это как-то связано с полным методом, который, как он утверждает, вызывается внутри. Но я не могу назвать себя полным, хотя это упоминается в документах.

  • Почему у nexus 7 4.2.1 получается другая неделя, чем у всех других моих устройств/эмуляторов, когда функции календаря подаются точно такие же параметры.

Странный.

person Madhava Jay    schedule 21.01.2013