Get Last Friday of Month in Java
我正在一个项目中,要求将日期计算为给定月份的最后一个星期五。 我认为我有一个仅使用标准Java的解决方案,但我想知道是否有人知道更简洁或更有效的方法。 以下是我今年测试的内容:
1 2 3 4 5 6 7 8 9 10 11 12
| 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());
} |
让Calendar.class为您做魔术吧;)
1 2
| pCal.set(GregorianCalendar.DAY_OF_WEEK,Calendar.FRIDAY);
pCal.set(GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1); |
根据marked23的建议:
1 2 3 4 5 6
| 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();
} |
java.time
使用Java 8和更高版本中内置的java.time库,您可以使用TemporalAdjusters.lastInMonth:
1 2
| val now = LocalDate.now()
val lastInMonth = now.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)) |
您可以从DayOfWeek枚举中选择任意一天。
如果您需要添加时间信息,则可以使用任何可用的LocalDate到LocalDateTime转换,例如
1
| lastFriday.atStartOfDay() // e.g. 2015-11-27T00:00 |
您无需循环就可以找到答案。要确定本月的"最后星期五"日期,请从下个月的第一天开始。减去适当的天数,具体取决于该月的第一天是星期几(数字)。有你的"上周五"。我很确定它可以简化为冗长的单行代码,但是我不是Java开发人员。所以我将其留给其他人。
我会使用像Jodatime这样的库。它具有非常有用的API,并且使用正常的月份数。最重要的是,它是线程安全的。
我认为您可以采用以下解决方案(但可能不是最短的解决方案,但肯定更具可读性):
1 2 3 4 5 6
| 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); |
您需要知道两件事-一个月中的天数以及该月中第一天的工作日。
如果该月的第一天是
-
星期日,然后最后一个星期五始终是27日。
-
星期一,然后最后一个星期五始终是26日。
-
星期二,那么最后一个星期五始终是25日。
-
星期三,然后最后一个星期五是第24个,除非一个月中有31天,那么它是第31个
-
星期四,然后最后一个星期五是23日,除非一个月中有30天或更多,则为30日。
-
星期五,然后最后一个星期五是22日,除非一个月中有29天或更多,则它是29日。
-
星期六,然后最后一个星期五始终是28日。
只有三种特殊情况。一个switch语句和三个if语句(如果您希望每种情况都只有一行,则为三元运算符...)
在纸上解决。不需要任何特殊的库,函数,julian转换等(嗯,除了获得1日的工作日,还有该月的天数...)
Aaron用Java实现了它。
-亚当
亚当·戴维斯算法的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| 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?");
}} |
以下是获取每月的最后一个星期五或每周几的方法:
1 2 3 4 5
| 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. |
在Java 8中,我们可以简单地做到这一点:
1 2 3 4
| LocalDate lastFridayOfMonth = LocalDate
.now()
.with(lastDayOfMonth())
.with(previous(DayOfWeek.FRIDAY)); |
尽管我同意scubabbl,但这是一个没有时间的版本。
1 2 3 4 5 6 7 8 9 10 11
| 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());
} |
下面的节目是每个月的最后一个星期五。它可用于获取任何月份中星期几的最后一天。变量offset=0表示当前月份(系统日期),offset = 1表示下个月,依此类推。 getLastFridayofMonth(int offset)方法将返回最后一个星期五。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 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
}
} |
稍微简单易读的暴力方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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;
} |
这看起来是一个完全可以接受的解决方案。如果可行,请使用它。那是最少的代码,除非有必要,否则没有理由对其进行优化。
1 2 3 4 5 6 7
| 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));
} |
希望这可以帮助..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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);
} |
1 2 3 4 5 6 7
| 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;
} |
|