Получить день начала и конец недели? [Джава]
Я занимаюсь разработкой приложения, которое постоянно отслеживает физическую активность и уровни неактивности пользователя. Я пытаюсь найти начальный и конечный день недели, когда указана дата. Например, 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;
}