Получить день начала и конец недели? [Джава]

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

Я пытаюсь добиться следующего дизайна введите описание изображения здесь

Следующий код, который у меня в данный момент только что объединяет последнюю и первую дату списка действий (создается по одному на каждый день).

private String formatDate(List<Activity> activities) {
    Calendar calendar = Calendar.getInstance(Locale.UK);
    Date date = activities.get(activities.size() - 1).getDate();
    calendar.setTime(date);
    String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);

    calendar.setTime(activities.get(0).getDate());

    output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    return output;
}

Примечание: я должен отметить, что список в качестве параметра - это все действия, сгруппированные по неделям.

Тем не менее, при таком подходе становится проблематичным, когда человек не использует приложение (т.е. не вошел в систему -> приложение прекращает мониторинг), и текстовая метка может выглядеть примерно так введите описание изображения здесь (например, только одно занятие на этой неделе)

Любой совет, пожалуйста?

4 ответа

Решение

Это так же просто, как сделать:

calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());

То, что считается первым днем ​​недели, зависит от Locale используемый.

Чтобы получить последний день недели, выполните:

calendar.add(Calendar.DAY_OF_YEAR, 6);

java.time

Устаревший API даты и времени ( java.util типы даты и времени и тип их форматирования, SimpleDateFormatи т. д.) устарело и подвержено ошибкам. Рекомендуется полностью прекратить его использование и перейти на *.

Решение с использованием современного API:

Для недели ISO 8601 (с понедельника по воскресенье) вы можете использовать ChronoField.DAY_OF_WEEK как 1 для первого дня недели и как 7 для последнего дня недели.

      import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoField;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2017, Month.MARCH, 3);

        LocalDate firstDayOfTheWeek = date.with(ChronoField.DAY_OF_WEEK, 1);
        System.out.println(firstDayOfTheWeek); // 2017-02-27

        LocalDate lastDayOfTheWeek = date.with(ChronoField.DAY_OF_WEEK, 7);
        System.out.println(lastDayOfTheWeek); // 2017-03-05
    }
}

В качестве альтернативы,

      import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.WeekFields;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2017, Month.MARCH, 3);

        LocalDate firstDayOfTheWeek = date.with(WeekFields.ISO.getFirstDayOfWeek());
        System.out.println(firstDayOfTheWeek); // 2017-02-27

        LocalDate lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
        System.out.println(lastDayOfTheWeek); // 2017-03-05
    }
}

Использовать WeekFields#of(Locale locale) чтобы получить Locale-конкретный результат (спасибо Оле В.В. за предложение):

      import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.WeekFields;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2017, Month.MARCH, 3);

        System.out.println("France:");
        LocalDate firstDayOfTheWeek = date.with(WeekFields.of(Locale.FRANCE).getFirstDayOfWeek());
        System.out.println(firstDayOfTheWeek);

        LocalDate lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
        System.out.println(lastDayOfTheWeek);

        System.out.println();
        System.out.println("USA:");
        firstDayOfTheWeek = date.with(WeekFields.of(Locale.US).getFirstDayOfWeek());
        System.out.println(firstDayOfTheWeek);

        lastDayOfTheWeek = firstDayOfTheWeek.plusDays(6);
        System.out.println(lastDayOfTheWeek);
    }
}

Выход:

      France:
2017-02-27
2017-03-05

USA:
2017-03-05
2017-03-11

Документация WeekFields.ISO.getFirstDayOfWeek() говорит:

Получает первый день недели.

Первый день недели зависит от культуры. Например, в США используется воскресенье, а во Франции и стандарте ISO-8601 - понедельник. Этот метод возвращает первый день с использованием стандартного перечисления DayOfWeek.

Узнать больше о java.time, современный API даты и временисовременный API даты и времени* из Trail: Date Time .


* По любой причине, если вам нужно придерживаться Java 6 или Java 7, вы можете использовать ThreeTen-Backport, который поддерживает большую часть функциональности java.time для Java 6 и 7. Если вы работаете над проектом Android и своим Android API уровень по-прежнему не соответствует Java-8, проверьте API-интерфейсы Java 8+, доступные через десугаринг, и Как использовать ThreeTenABP в Android Project .

Вам просто нужно использовать Calendar.DAY_OF_WEEK Параметр для определения количества вычитаемых дней - например, для печати начала и конца текущей недели:

public static void main(String[] args) {
    Calendar calendar = GregorianCalendar.getInstance();

    // Subtract number of days to start of week
    calendar.add(Calendar.DATE, -(calendar.get(Calendar.DAY_OF_WEEK)-1));

    String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    calendar.add(Calendar.DATE, 6);
    output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    System.out.println(output);
}

Благодаря @BarrySW19 и @john16384, вот рабочий метод:

private String formatDate(List<Activity> activities) {
    Calendar calendar = Calendar.getInstance(Locale.UK);
    Date date = activities.get(activities.size() - 1).getDate();
    calendar.setTime(date);
    calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());

    String output = "" + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);

    calendar.add(Calendar.DAY_OF_YEAR, 6);

    output += " - " + calendar.get(Calendar.DAY_OF_MONTH) + " "
            + calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.UK);
    return output;
}
Другие вопросы по тегам