计算两个日期(不包括周末)的日期

我在Spring 3.0项目中使用Joda time api来计算日期。 现在我有一个开始和结束日期,我希望在这两个日期之间每周周末或周六或周日进行。 我怎样才能做到这一点?

我看了这篇postJoda时间 – 两个约会之间的所有星期一 。 它提供了一些指导,但仍然含糊不清,如何排除两个日期。

我假设你的问题是如何

每天除了周末或周六或周日之间的两个日期。

方案

 public static void main(String[] args) { final LocalDate start = LocalDate.now(); final LocalDate end = new LocalDate(2012, 1, 14); LocalDate weekday = start; if (start.getDayOfWeek() == DateTimeConstants.SATURDAY || start.getDayOfWeek() == DateTimeConstants.SUNDAY) { weekday = weekday.plusWeeks(1).withDayOfWeek(DateTimeConstants.MONDAY); } while (weekday.isBefore(end)) { System.out.println(weekday); if (weekday.getDayOfWeek() == DateTimeConstants.FRIDAY) weekday = weekday.plusDays(3); else weekday = weekday.plusDays(1); } } 

我是新来的。 我一直在寻找这个问题的解决方案,并没有使用循环,但没有找到合适的算法。 所以我决定创建这个解决方案不使用循环,非常高效并且代码已经过测试。

 public int betweenDaysIgnoreWeekends(DateTime startDate, DateTime endDate) { //Um numero que representa o dia da semana para a data final, exemplo segunda=1, terça=2, quarta=3... int dayOfWeekEndDateNumber = Integer.valueOf(endDate.dayOfWeek() .getAsString()); //Um numero que representa o dia da semana para a data inicial, exemplo segunda=1, terça=2, quarta=3... int dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek() .getAsString()); //Se a data final for sabado ou domingo, finja ser sexta-feira if (dayOfWeekEndDateNumber == 6 || dayOfWeekEndDateNumber == 7) { int DaysToAdd = 8 - dayOfWeekEndDateNumber; endDate = endDate.plusDays(DaysToAdd); dayOfWeekEndDateNumber = Integer.valueOf(endDate.dayOfWeek() .getAsString()); } //Se a data inicial for sabado ou domingo, finja ser segunda-feira if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) { int DaysToAdd = 8 - dayOfWeekStartDateNumber; startDate = startDate.plusDays(DaysToAdd); dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek() .getAsString()); } //Quantos dias se passaram contando os fins de semana int days = Days.daysBetween(startDate, endDate).getDays(); //Quantas semanas se passaram exatamente int weeks = days / 7; //O excesso de dias que sobrou, exemplo: 1 semana e 3 dias o excess=3 e weeks=1 int excess = days % 7; //Se a data inicial for igual a data final, passou 0 dia if (startDate.equals(endDate)) { return 0; } else { //O excesso de dias passou pelo fim de semana, então deve-se retirar 2 dias //da quantidade final de dias if (excess + dayOfWeekStartDateNumber >= 6) { //Quantidade de semanas * 5 dias uteis + o excesso de dias - o final de semana que o excesso atravessou return weeks * 5 + excess - 2; } //Quantidade de semanas * 5 dias uteis + o excesso de dias return weeks * 5 + excess; } } 

为了改进@ samir-machado-de-oliveira发布的内容,这里有一个函数可以在不使用循环的情况下计算周末的数量。 我没有对循环版本进行基准测试,但看起来好像会更快:

 /** * Gets number of days between two dates. Ignoring weekends. * @param startDate * @param endDate * @return */ public static int getDaysBetweenIgnoreWeekends(DateTime startDate, DateTime endDate) { // If the start date is equal to the closing date, spent 0 days if (startDate.equals(endDate)) return 0; // A number that represents the day for the start date, Monday = 1 , Tuesday = 2 , Wednesday = 3 ... int dayOfWeekStartDateNumber = startDate.getDayOfWeek(); // If the starting date is Saturday or Sunday , pretend to be Monday if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) { int DaysToAdd = 8 - dayOfWeekStartDateNumber; startDate = startDate.plusDays(DaysToAdd); dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek().getAsString()); } // How many days have passed counting weekends int days = Days.daysBetween(startDate, endDate).getDays(); // How many weeks have passed int weeks = days / 7; // Excess days left. Eg one week and three days the excess will be 3 int excess = days % 7; // Excess of days spent for the weekend , then it must be removed two days // the final number of days if (excess + dayOfWeekStartDateNumber >= 6) { // Week count * 5 working days + excess days - the weekend that excess crossed return weeks * 5 + excess - 2; } // Weeks count * 5 working days + excess days return weeks * 5 + excess; } 

此外,这里有一个允许你忽略当天时间的版本,因此如果开始日期是开始时间的上午11点,结束时间是上午10点的第二天,它将显示为1天而不是0天。

 /** * Gets number of days between two dates. Ignoring weekends. Ignores Hours. * @param startDate * @param endDate * @return */ public static int getDaysBetweenIgnoreWeekends(DateTime startDate, DateTime endDate) { return getDaysBetweenIgnoreWeekends(startDate,endDate,true); } /** * Gets number of days between two dates. Ignoring weekends. * @param startDate * @param endDate * @param ignoreTimeOfDay * @return */ public static int getDaysBetweenIgnoreWeekends(DateTime startDate, DateTime endDate, boolean ignoreTimeOfDay) { // If the start date is equal to the closing date, spent 0 days if (startDate.equals(endDate)) return 0; if (ignoreTimeOfDay && startDate.toLocalDate().equals(endDate.toLocalDate())) return 0; // A number that represents the day for the start date, Monday = 1 , Tuesday = 2 , Wednesday = 3 ... int dayOfWeekStartDateNumber = startDate.getDayOfWeek(); // If the starting date is Saturday or Sunday , pretend to be Monday if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) { int DaysToAdd = 8 - dayOfWeekStartDateNumber; startDate = startDate.plusDays(DaysToAdd); dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek().getAsString()); } // How many days have passed counting weekends int days; if(ignoreTimeOfDay) { days = Days.daysBetween(startDate.toLocalDate(), endDate.toLocalDate()).getDays(); } else { days = Days.daysBetween(startDate, endDate).getDays(); } // How many weeks have passed int weeks = days / 7; // Excess days left. Eg one week and three days the excess will be 3 int excess = days % 7; // Excess of days spent for the weekend , then it must be removed two days // the final number of days if (excess + dayOfWeekStartDateNumber >= 6) { // Week count * 5 working days + excess days - the weekend that excess crossed return weeks * 5 + excess - 2; } // Weeks count * 5 working days + excess days return weeks * 5 + excess; } 

我一直在使用@Josh Maag的逻辑差不多一年了,但最近发现当endDate恰好落在星期六时它会返回错误的值。

这是我想要分享的版本,它考虑从endDate中减去天数,恰好是星期六或星期日。

 public static int getDaysBetweenIgnoreWeekends(org.joda.time.DateTime startDate, org.joda.time.DateTime endDate, boolean ignoreTimeOfDay) { // If the start date is equal to the closing date, spent 0 days if (startDate.equals(endDate)) return 0; if (ignoreTimeOfDay && startDate.toLocalDate().equals(endDate.toLocalDate())) return 0; // A number that represents the day for the start date, Monday = 1 , Tuesday = 2 , Wednesday = 3 ... int dayOfWeekStartDateNumber = startDate.getDayOfWeek(); int dayOfWeekEndDateNumber = endDate.getDayOfWeek(); // If the starting date is Saturday or Sunday , pretend to be Monday if (dayOfWeekStartDateNumber == 6 || dayOfWeekStartDateNumber == 7) { int DaysToAdd = 8 - dayOfWeekStartDateNumber; startDate = startDate.plusDays(DaysToAdd); dayOfWeekStartDateNumber = Integer.valueOf(startDate.dayOfWeek().getAsString()); } org.joda.time.DateTime effectiveEndDate = endDate; if (dayOfWeekEndDateNumber == 6 || dayOfWeekEndDateNumber == 7) { effectiveEndDate = endDate.minusDays(Math.abs(5 - dayOfWeekEndDateNumber)); } // How many days have passed counting weekends int days; if(ignoreTimeOfDay) { days = org.joda.time.Days.daysBetween(startDate.toLocalDate(), effectiveEndDate.toLocalDate()).getDays(); } else { days = org.joda.time.Days.daysBetween(startDate, effectiveEndDate).getDays(); } // How many weeks have passed int weeks = days / 7; // Excess days left. Eg one week and three days the excess will be 3 int excess = days % 7; // Excess of days spent for the weekend , then it must be removed two days // the final number of days if (excess + dayOfWeekStartDateNumber >= 6) { // Week count * 5 working days + excess days - the weekend that excess crossed return weeks * 5 + excess - 2; } // Weeks count * 5 working days + excess days return weeks * 5 + excess; } 

在早期版本中 – 以下代码段减去额外的一天。 无论endDate是星期六还是星期日,都减去-2。

 if (excess + dayOfWeekStartDateNumber >= 6) { // Week count * 5 working days + excess days - the weekend that excess crossed return weeks * 5 + excess - 2; } 

希望有所帮助!

您可以使用格里高利历来检索特定日期的日期。 如果字符串是星期六或星期日,你可以忽略它。

这将通过排除周末来返回结束日期

 public static Date addDaysBySkipWeekend(Date startDate, int numDays) { Calendar dateCal = Calendar.getInstance(); dateCal.setTime(startDate); for (int i = 0; i < numDays-1; i++) { dateCal.add(dateCal.DATE, 1); if(dateCal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || dateCal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ){ dateCal.add(dateCal.DATE, 1); i--; } } return dateCal.getTime(); } 

整齐地使用Java 8 Streams:

  public LocalDate[] filterWeekdaysForRange(final LocalDate start,final LocalDate end) { return Stream.iterate(start, date -> date.plusDays(1)) .limit(ChronoUnit.DAYS.between(start, end)+1) .filter(d->d.getDayOfWeek() != SATURDAY) .filter(d->d.getDayOfWeek() != SUNDAY) .toArray(LocalDate[]::new); } 

这是对此处提供的解决方案的改编: https : //stackoverflow.com/a/38220748/744133