Получить последнюю пятницу месяца в Java
Я работаю над проектом, в котором требование должно иметь дату, рассчитанную как последнюю пятницу данного месяца. Я думаю, что у меня есть решение, которое использует только стандартную Java, но мне было интересно, знает ли кто-нибудь о чем-то более кратким или эффективным. Ниже я тестирую в этом году:
for (int month = 0; month < 13; month++) {
GregorianCalendar d = new GregorianCalendar();
d.set(d.MONTH, month);
System.out.println("Last Week of Month in " + d.getDisplayName(d.MONTH, Calendar.LONG, Locale.ENGLISH) + ": " + d.getLeastMaximum(d.WEEK_OF_MONTH));
d.set(d.DAY_OF_WEEK, d.FRIDAY);
d.set(d.WEEK_OF_MONTH, d.getActualMaximum(d.WEEK_OF_MONTH));
while (d.get(d.MONTH) > month || d.get(d.MONTH) < month) {
d.add(d.WEEK_OF_MONTH, -1);
}
Date dt = d.getTime();
System.out.println("Last Friday of Last Week in " + d.getDisplayName(d.MONTH, Calendar.LONG, Locale.ENGLISH) + ": " + dt.toString());
}
Ответы
Ответ 1
Основываясь на помечены23:
public Date getLastFriday( int month, int year ) {
Calendar cal = Calendar.getInstance();
cal.set( year, month + 1, 1 );
cal.add( Calendar.DAY_OF_MONTH, -( cal.get( Calendar.DAY_OF_WEEK ) % 7 + 1 ) );
return cal.getTime();
}
Ответ 2
Пусть Calendar.class сделает для вас свою магию;)
pCal.set(GregorianCalendar.DAY_OF_WEEK,Calendar.FRIDAY);
pCal.set(GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1);
Ответ 3
Вам не нужно зацикливать, чтобы это выяснить. Для определения даты "последней пятницы" в этом месяце, начните с первого дня следующего месяца. Вычтите соответствующее количество дней в зависимости от того, какой (числовой) день недели наступает первый день месяца. Там ваша "последняя пятница". Я почти уверен, что это можно свести к длинному однострочному, но я не разработчик Java. Поэтому я оставлю это кому-то еще.
Ответ 4
Я бы использовал библиотеку, например Jodatime. Он имеет очень полезный API и использует обычные номера месяца. И, что лучше всего, это безопасный поток.
Я думаю, что вы можете иметь решение с (но, возможно, не самым коротким, но, конечно, более читаемым):
DateTime now = new DateTime();
DateTime dt = now.dayOfMonth().withMaximumValue().withDayOfWeek(DateTimeConstants.FRIDAY);
if (dt.getMonthOfYear() != now.getMonthOfYear()) {
dt = dt.minusDays(7);
}
System.out.println(dt);
Ответ 5
java.time
Использование java.time библиотека, встроенная в Java 8 и более поздние версии:
import java.time.{DayOfWeek, LocalDate}
import java.time.temporal.TemporalAdjusters.lastInMonth
val now = LocalDate.now() # 2015-11-23
val lastInMonth = now.`with`(lastInMonth(DayOfWeek.FRIDAY)) # 2015-11-27
Вы можете выбрать любой день из DayOfWeek
enum: java.time.DayOfWeek.{MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
.
Если вам нужно добавить информацию о времени, вы можете использовать любые доступные LocalDate
для LocalDateTime
, например
lastFriday.atStartOfDay() # 2015-11-27T00:00
Ответ 6
Вам нужно знать две вещи: количество дней в месяце и день недели, когда наступает первый месяц.
Если первый день месяца -
- Воскресенье, тогда последняя пятница всегда 27-го.
- Понедельник, затем последняя пятница всегда 26-го.
- Вторник, тогда последняя пятница всегда 25-го.
- Среда, затем последняя пятница - 24-е, если в месяце нет 31 дня, то это 31-й
- Четверг, затем в последнюю пятницу 23-го, если в месяце не было 30 или более дней, то это 30-е.
- Пятница, тогда последняя пятница - 22-е, если в месяце не будет 29 дней или более, тогда это 29-й.
- Суббота, тогда последняя пятница всегда 28-го.
Есть только три особых случая. Единый оператор switch и три оператора if (или тройные операторы, если вы хотите, чтобы каждый случай имел одну строку...)
Работайте на бумаге. Не нужно никаких специальных библиотек, функций, юлианских конверсий и т.д. (Ну, кроме того, чтобы получить день недели, на который приходится 1 день, а может быть и число дней в этом месяце...)
Аарон реализовал его на Java.
-Adam
Ответ 7
код для алгоритм Адама Дэвиса
public static int getLastFriday(int month, int year)
{
Calendar cal = Calendar.getInstance();
cal.set(year, month, 1, 0, 0, 0); // set to first day of the month
cal.set(Calendar.MILLISECOND, 0);
int firstDay = cal.get(Calendar.DAY_OF_WEEK);
int daysOfMonth = cal.getMaximum(Calendar.DAY_OF_MONTH);
switch (firstDay)
{
case Calendar.SUNDAY :
return 27;
case Calendar.MONDAY :
return 26;
case Calendar.TUESDAY :
return 25;
case Calendar.WEDNESDAY :
if (daysOfMonth == 31) return 31;
return 24;
case Calendar.THURSDAY :
if (daysOfMonth >= 30) return 30;
return 23;
case Calendar.FRIDAY :
if (daysOfMonth >= 29) return 29;
return 22;
case Calendar.SATURDAY :
return 28;
}
throw new RuntimeException("what day of the month?");
}}
Ответ 8
Это выглядит вполне приемлемым решением. Если это работает, используйте его. Это минимальный код, и нет никаких оснований для его оптимизации, если вам не нужно.
Ответ 9
Это не сработает. Ваш цикл будет цикл 13 раз (от 0 до 12).
Ответ 10
Немного легче читать, использовать грубую силу:
public int getLastFriday(int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(year, month, 1, 0, 0, 0); // set to first day of the month
cal.set(Calendar.MILLISECOND, 0);
int friday = -1;
while (cal.get(Calendar.MONTH) == month) {
if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) { // is it a friday?
friday = cal.get(Calendar.DAY_OF_MONTH);
cal.add(Calendar.DAY_OF_MONTH, 7); // skip 7 days
} else {
cal.add(Calendar.DAY_OF_MONTH, 1); // skip 1 day
}
}
return friday;
}
Ответ 11
Хотя я согласен с scubabbl, вот версия без внутреннего.
int year = 2008;
for (int m = Calendar.JANUARY; m <= Calendar.DECEMBER; m++) {
Calendar cal = new GregorianCalendar(year, m, 1);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
int diff = Calendar.FRIDAY - cal.get(Calendar.DAY_OF_WEEK);
if (diff > 0) {
diff -= 7;
}
cal.add(Calendar.DAY_OF_MONTH, diff);
System.out.println(cal.getTime());
}
Ответ 12
Ниже программа предназначена для последней пятницы каждого месяца. его можно использовать для получения последнего из любого дня недели в любой месяц. Переменная offset=0
означает текущий месяц (системная дата), смещение = 1 означает следующий месяц и так далее. Метод getLastFridayofMonth(int offset)
вернется в прошлую пятницу.
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class LastFriday {
public static Calendar getLastFriday(Calendar cal,int offset){
int dayofweek;//1-Sunday,2-Monday so on....
cal.set(Calendar.MONTH,cal.get(Calendar.MONTH)+offset);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH)); //set calendar to last day of month
dayofweek=cal.get(Calendar.DAY_OF_WEEK); //get the day of the week for last day of month set above,1-sunday,2-monday etc
if(dayofweek<Calendar.FRIDAY) //Calendar.FRIDAY will return integer value =5
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)-7+Calendar.FRIDAY-dayofweek);
else
cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)+Calendar.FRIDAY-dayofweek);
return cal;
}
public static String getLastFridayofMonth(int offset) { //offset=0 mean current month
final String DATE_FORMAT_NOW = "dd-MMM-yyyy";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
cal=getLastFriday(cal,offset);
return sdf.format(cal.getTime());
}
public static void main(String[] args) {
System.out.println(getLastFridayofMonth(0)); //0 = current month
System.out.println(getLastFridayofMonth(1));//1=next month
System.out.println(getLastFridayofMonth(2));//2=month after next month
}
}
Ответ 13
Существует ряд полезных методов для вычисления дня недели. С небольшим количеством добавленной алгебры, один из них должен быть адаптирован к вашей проблеме.
Ответ 14
Решение ColinD не должно работать: попробуйте запустить его с декабря 2008 года, и он попытается установить 13-й месяц в году. Однако замена "cal.set(...)" на "cal.add(Calendar.MONTH, 1)" должна работать нормально.
Ответ 15
Надеюсь, что это поможет.
public static void getSundaysInThisMonth(int monthNumber, int yearNumber){
//int year =2009;
//int dayOfWeek = Calendar.SUNDAY;
// instantiate Calender and set to first Sunday of 2009
Calendar cal = new GregorianCalendar();
cal.set(Calendar.MONTH, monthNumber-1);
cal.set(Calendar.YEAR, yearNumber);
cal.set(Calendar.DATE, 1);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int dateOfWeek = cal.get(Calendar.DATE);
while (dayOfWeek != Calendar.SUNDAY) {
cal.set(Calendar.DATE, ++dateOfWeek);
dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
}
cal.set(Calendar.DATE, dateOfWeek);
int i = 1;
while (cal.get(Calendar.YEAR) == yearNumber && cal.get(Calendar.MONTH)==monthNumber-1)
{
System.out.println("Sunday " + " " + i + ": " + cal.get(Calendar.DAY_OF_MONTH));
cal.add(Calendar.DAY_OF_MONTH, 7);
i++;
}
}
public static void main(String args[]){
getSundaysInThisMonth(1,2009);
}
Ответ 16
здесь, как получить последний пятница или любой другой день недели месяца:
Calendar thisMonth = Calendar.getInstance();
dayOfWeek = Calendar.FRIDAY; // or whatever
thisMonth.set(Calendar.WEEK_OF_MONTH, thisMonth.getActualMaximum(Calendar.WEEK_OF_MONTH);;
thisMonth.set(Calendar.DAY_OF_WEEK, dayOfWeek);
int lastDay = thisMonth.get(Calendar.DAY_OF_MONTH); // this should be it.
Ответ 17
public static Calendar getNthDow(int month, int year, int dayOfWeek, int n) {
Calendar cal = Calendar.getInstance();
cal.set(year, month, 1);
cal.set(Calendar.DAY_OF_WEEK, dayOfWeek);
cal.set(Calendar.DAY_OF_WEEK_IN_MONTH, n);
return (cal.get(Calendar.MONTH) == month) && (cal.get(Calendar.YEAR) == year) ? cal : null;
}
Ответ 18
public static int lastSundayDate()
{
Calendar cal = getCalendarInstance();
cal.setTime(new Date(getUTCTimeMillis()));
cal.set( Calendar.DAY_OF_MONTH , 25 );
return (25 + 8 - (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY ? cal.get(Calendar.DAY_OF_WEEK) : 8));
}
Ответ 19
В Java 8 мы можем сделать это просто как:
LocalDate lastFridayOfMonth = LocalDate
.now()
.with(lastDayOfMonth())
.with(previous(DayOfWeek.FRIDAY));