Календарь возвращает плохое начало недели на некоторых устройствах Android - PullRequest
0 голосов
/ 28 мая 2018

Я хотел бы получить дату первого дня текущей недели.Поэтому я реализовал это следующим образом:

fun getFirstDayInCurrentWeek(): Date {
    val calendar = Calendar.getInstance()
    calendar.clear(MILLISECOND)
    calendar.clear(SECOND)
    calendar.clear(MINUTE)
    calendar.set(HOUR_OF_DAY, 0)
    calendar.set(DAY_OF_WEEK, 1)
    return calendar.time
}

Он работает на большинстве устройств, но иногда возвращает дату первого дня на следующей неделе.Я не могу понять, почему.

Классы происходят от java.util.*.

Редактировать: Просто зарегистрируйте результат этой функции сегодня (28.05.2018)и вы увидите либо 27.05.2018, либо 03.06.2018.Устройства имеют одинаковые локали и одинаковые часовые пояса.

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Если я правильно понимаю, вы хотите считать воскресенье первым днем ​​недели (как в США).

    WeekFields wf = WeekFields.SUNDAY_START;
    LocalDate today = LocalDate.now(ZoneId.of("Europe/Warsaw"));
    LocalDate firstDayOfThisWeek = today.with(wf.dayOfWeek(), 1);
    System.out.println(firstDayOfThisWeek);

Я пишу код Java и доверяю вам преобразоваться в Kotlin.Сегодня (вторник, 29 мая) это напечатано

2018-05-27

Если вместо этого вы хотите, чтобы понедельник был первым днем ​​недели (как в Польше и какмеждународный стандарт гласит), просто используйте WeekFields.ISO вместо WeekFields.SUNDAY_START.Если вы хотите, чтобы он зависел от локали, используйте, например, WeekFields.of(Locale.forLanguageTag("pl-PL")).

Другой и, возможно, более понятный вариант:

    LocalDate firstDayOfThisWeek = today
            .with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));

В обоих случаях я использую java.time, современную JavaAPI даты и времени.Я думаю, что это хороший пример того, где он обеспечивает более четкий код, что часто имеет место по сравнению со старыми классами даты и времени, такими как Calendar.

Что пошло не так в вашем коде?

Как я понимаю в документации, ваш код должен указывать на воскресенье текущей недели.Calendar использует 1 для воскресенья.Возможно, вы использовали calendar.set(DAY_OF_WEEK, SUNDAY), чтобы получить точно такой же.Когда я запускаю его сегодня, я получаю 27 мая при использовании воскресенья в качестве первого дня недели и 3 июня при использовании понедельника в качестве первого дня (что означает, что воскресенье - последний день недели).Однако документация не очень понятна, и класс Calendar может сбивать с толку.В любом случае, вероятно, именно это и произошло, когда вы попробовали на разных устройствах: у них были разные определения недель.Это может быть возможно, даже если они имеют одинаковый языковой стандарт, если вы можете настроить определения недели отдельно.

Вопрос: Можно ли использовать java.time на Android?

Да, java.time прекрасно работает настарые и новые устройства Android.Для этого требуется как минимум Java 6 .

  • В Java 8 и более поздних версиях и на более новых устройствах Android (от уровня API 26, как мне сказали), современный API поставляется встроенным.
  • В Java 6 и 7 получите ThreeTen Backport, бэкпорт новых классов (ThreeTen для JSR 310; см. ссылки внизу).
  • На (более старом) использовании AndroidAndroid-версия ThreeTen Backport.Это называется ThreeTenABP.И убедитесь, что вы импортируете классы даты и времени из org.threeten.bp с подпакетами.

Ссылки

0 голосов
/ 29 мая 2018

Первый день недели различен для разных стран.Если вы хотите, чтобы оно было одинаковым для всех пользователей, вы можете передать Locale Calendar.

Calendar currentCalendar = Calendar.getInstance(new Locale("en","UK"));

также из этого ответа. Вы можете использовать методsetFirstDayOfWeek (), чтобы установить первый день недели.Метод может влиять только на возвращаемые значения WEEK_OF_MONTH или WEEK_OF_YEAR.Для DAY_OF_WEEK это ничего не делает.

Вы можете реализовать что-то вроде:

Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
int rec = cal.get(Calendar.WEEK_OF_MONTH);
System.out.println(rec);

Подробнее об API ЗДЕСЬ

...