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