Получить дату текущей недели в понедельник

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

Calendar c = Calendar.getInstance();
c.setTime(new Date());
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_WEEK));
int mondayNo = c.get(Calendar.DAY_OF_MONTH)-c.get(Calendar.DAY_OF_WEEK)+2;
c.set(Calendar.DAY_OF_MONTH,mondayNo);
System.out.println("Date "+c.getTime());

9 ответов

Решение

Я бы настоятельно рекомендовал вместо этого использовать Joda Time (для всей вашей работы с датой / временем, а не только с этим):

// TODO: Consider time zones, calendars etc
LocalDate now = new LocalDate();
LocalDate monday = now.withDayOfWeek(DateTimeConstants.MONDAY);
System.out.println(monday);

Обратите внимание, что, поскольку вы использовали здесь понедельник, который является первым днем ​​недели в Joda Time, он всегда будет возвращать более ранний день (или тот же день). Если вы выбрали среду (например), то она перейдет на среду с понедельника или вторника. Вы всегда можете добавить или вычесть неделю, если вам нужна "следующая среда" или "предыдущая среда".

РЕДАКТИРОВАТЬ: Если вы действительно хотите использовать java.util.Date/Calendar, вы можете использовать:

Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());

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

ТЛ; др

LocalDate previousMonday = 
    LocalDate.now( ZoneId.of( "America/Montreal" ) )
             .with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) );

java.time

И класс java.util.Calendar, и библиотека Joda-Time были вытеснены фреймворком java.time, встроенным в Java 8 и более поздние версии. Смотрите Oracle Tutorial. Большая часть функциональности java.time была перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP.

java.time.LocalDate класс представляет значение только для даты без времени суток и без часового пояса.

Для определения сегодняшней даты требуется часовой пояс, ZoneId,

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );

TemporalAdjuster Интерфейс (см. Учебное пособие) является мощным, но простым способом манипулирования значениями даты и времени. TemporalAdjusters Класс (обратите внимание на множественное число) реализует некоторые очень полезные настройки. Здесь мы используем previous( DayOfWeek),

Удобный DayOfWeek enum позволяет легко определить день недели.

LocalDate previousMonday = today.with( TemporalAdjusters.previous( DayOfWeek.MONDAY ) );

Если сегодня понедельник, и вы хотите использовать сегодня, а не неделю назад, позвоните previousOrSame,


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date, Calendar & SimpleDateFormat,

Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.

Чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310.

Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классы.

Где взять классы java.time?

  • Java SE 8, Java SE 9 и более поздние
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (<26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше). Смотрите Как использовать ThreeTenABP….

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как Interval, YearWeek, YearQuarter и многое другое.

Следующее будет работать, включая месяцы упаковки:

Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.setTime(new Date());
int today = c.get(Calendar.DAY_OF_WEEK);
c.add(Calendar.DAY_OF_WEEK, -today+Calendar.MONDAY);
System.out.println("Date "+c.getTime());

Однако, если вы редактируете свою заявку в воскресенье (например, воскресенье 12 февраля), дата будет следующей понедельник. Исходя из ваших требований (приложение будет работать только с понедельника по пятницу), это не должно вызывать проблем.

Как предположил Джон, метод calendar.set работает... Я проверил его как в случае понедельника в том же месяце, так и в другом месяце, используя следующий фрагмент:

Calendar c = Calendar.getInstance();
//ensure the method works within current month
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());
//go to the 1st week of february, in which monday was in january
c.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("Date " + c.getTime());
//test that setting day_of_week to monday gives a date in january
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
System.out.println("Date " + c.getTime());
//same for tuesday
c.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
System.out.println("Date " + c.getTime());

Результаты, достижения:

Date Mon Feb 13 10:29:41 CET 2012
Date Wed Feb 01 10:29:41 CET 2012
Date Mon Jan 30 10:29:41 CET 2012
Date Tue Jan 31 10:29:41 CET 2012

Как насчет использования библиотеки Joda Time... Посмотрите на этот ответ...

Если вы не хотите использовать Joda Time, вы можете сделать так, чтобы найти недели -> (работает на Android)

public static ArrayList<String> getWeeks(int month) {

ArrayList<String> arrayListValues = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("MMMM d");

Calendar calendar = Calendar.getInstance();

calendar.set(Calendar.MONTH, month);

int day = calendar.get(Calendar.DAY_OF_WEEK);
while (day != 1) {
  calendar.add(Calendar.DATE, 1);
  day = calendar.get(Calendar.DAY_OF_WEEK);
}

calendar.add(Calendar.DATE, -14);
String y1 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 6);
String y2 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 1);
arrayListValues.add(y1 + " - " + y2);

 y1 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 6);
 y2 = sdf.format(calendar.getTime());
calendar.add(Calendar.DATE, 1);
arrayListValues.add(y1 + " - " + y2);



for (int i = 0; i < 10; i++) {

  y1 = sdf.format(calendar.getTime());
  calendar.add(Calendar.DATE, 6);
  y2 = sdf.format(calendar.getTime());
  calendar.add(Calendar.DATE, 1);
  arrayListValues.add(y1 + " - " + y2);
}

return arrayListValues;
}

Для версии Android 6.0 или терки используйте:

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
int day = 8, month = 2, year = 2019;
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
//set the date with your date or the current date c.set(new Date());
c.set(year, month, day);
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);  //change de day to monday
String dateMonday= sdf.format(c.getTime());

Для версии Android 5.1 или ниже она не работает должным образом, я создал свой собственный метод.

SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
int day = 8, month = 2, year = 2019;
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
//set the date with your date or the current date c.set(new Date());
c.set(year, month, day);

int diaSemana = c.get(Calendar.DAY_OF_WEEK);
for (int i = 0; i < 7; i++) {
   if (diaSemana != Calendar.MONDAY) {
     if (day > 2) {
       day--;
       c.set(year, month, day);
       diaSemana = c.get(Calendar.DAY_OF_WEEK);
     } else {
       if (month > 0) {
       month--;
       c.set(year, month, 1);
       day = c.getActualMaximum(Calendar.DAY_OF_MONTH);
       c.set(year, month, day);
     } else {
       month = 12;
       year--;
       c.set(year, month, 31);
     }
     diaSemana = c.get(Calendar.DAY_OF_WEEK);
    }
   } else {
   break;
   }
 }
String dateMonday= sdf.format(c.getTime());

Код Котлина. Работает в более старых версиях Android

          val c = Calendar.getInstance()
    c.time = Date()
    
    while (c.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
        c.add(Calendar.DAY_OF_WEEK, -1)
    }

Это не сработает, если понедельник текущей недели - это месяц раньше... Например, если сегодня пятница, 1 июня... Возможно, вам лучше использовать метод roll...

Другие вопросы по тегам