在Java中获得上个星期五的月份

我正在开发一个项目,其中要求将日期计算为给定月份的最后一个星期五。 我想我有一个只使用标准Java的解决方案,但我想知道是否有人知道更简洁或更有效的东西。 以下是我今年测试的内容:

for (int month = 0; 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()); } 

基于标记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(); } 

让Calendar.class为你做神奇的事;)

 pCal.set(GregorianCalendar.DAY_OF_WEEK,Calendar.FRIDAY); pCal.set(GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1); 

你永远不需要循环来找到它。 要确定本月的“上周五”日期,请从下个月的第一天开始。 减去适当的天数,具体取决于每月第一天的某一天(数字)日期。 这是你的“上周五”。 我很确定它可以归结为一个冗长的单行程序,但我不是一个java开发人员。 所以我会把它留给别人。

我会使用像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); 

java.time

使用Java 8及更高版本中内置的java.time库:

 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枚举中选择任何一天: java.time.DayOfWeek.{MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}

如果您需要添加时间信息,可以使用任何可用的LocalDateLocalDateTime转换

 lastFriday.atStartOfDay() # 2015-11-27T00:00 

您需要知道两件事 – 本月的天数和本月的第一天的工作日。

如果该月的第一天是

  • 星期天,那么最后一个星期五总是 27日。
  • 星期一,那么最后一个星期五总是 26日。
  • 星期二,那么上周五总是 25日。
  • 星期三,那么最后一个星期五是24日,除非这个月有31天,那么它是第31天
  • 星期四,那么最后一个星期五是23日,除非这个月有30天或更长时间,那么它是30日。
  • 星期五,那么最后一个星期五是22日,除非本月有29天或更长时间,那么它是第29天。
  • 星期六,那么上周五总是 28日。

只有三个特例。 一个switch语句和三个if语句(如果你喜欢每个case都有一行三元运算符……)

在纸上解决。 不需要任何特殊的库,函数,朱利安转换等(好吧,除了让第一个工作日到来,也许那个月的天数……)

Aaron用Java实现了它。

-亚当

Adam Davis算法的代码

 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?"); }} 

这看起来是完全可以接受的解决方案 如果可行,请使用它。 这是最小的代码,除非必须,否则没有理由对其进行优化。

那不行。 你的循环将循环13次(0到12)。

虽然我同意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()); } 

稍微容易阅读,蛮力方法:

 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; } 

这是如何获得本月的最后一个星期五或任何工作日:

 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. 

以下程序是每个月的最后一个星期五。 它可用于获取任何一个月中任何一天的最后一天。 变量offset=0表示当前月份(系统日期),offset = 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 

在Java 8中,我们可以简单地这样做:

 LocalDate lastFridayOfMonth = LocalDate .now() .with(lastDayOfMonth()) .with(previous(DayOfWeek.FRIDAY)); 

有许多有用的方法可用于计算星期几 。 通过一些额外的代数,其中一个应该适应您的问题。

ColinD的解决方案不起作用:尝试在2008年12月运行它,它将尝试设置一年的第13个月。 但是,将“cal.set(…)”替换为“cal.add(Calendar.MONTH,1)”应该可以正常工作。

 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; } 
 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)); } 

希望这可以帮助..

 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); }