2016-07-18 6 views
2

Я хочу, чтобы получить количество рабочих дней в конкретном месяцеполучить количество рабочих дней в конкретном месяце

в моем случае выходных дней являются Пятницами и суббота

Я использую этот код :

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Date; 
import java.util.GregorianCalendar; 

public class TestWeekDay { 

    /** 
    * @param args 
    * @throws ParseException 
    */ 
    public static void main(String[] args) throws ParseException { 

     // TODO Auto-generated method stub 


     SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy"); 
     String dateInString = "01-07-2016"; 
     Date startDate = sdf.parse(dateInString); 
     String dateInString2 = "31-07-2016"; 
     Date endDate = sdf.parse(dateInString2); 
     calculateDuration(startDate,endDate); 

    } 



    public static int calculateDuration(Date startDate, Date endDate) 
    { 
     Calendar startCal = Calendar.getInstance(); 
     startCal.setTime(startDate); 

     Calendar endCal = Calendar.getInstance(); 
     endCal.setTime(endDate); 

     int workDays = 0; 

     if (startCal.getTimeInMillis() > endCal.getTimeInMillis()) 
     { 
     startCal.setTime(endDate); 
     endCal.setTime(startDate); 
     } 

     do 
     { 
     startCal.add(Calendar.DAY_OF_MONTH, 1); 
     if (startCal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY && startCal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) 
     { 
      workDays++; 
     } 
     } 
     while (startCal.getTimeInMillis() <= endCal.getTimeInMillis()); 

     return workDays; 
    } 

} 

, когда я проверить, например, за июль месяц у меня есть и правильный ответ должен быть

+0

Пожалуйста, смотрите [Что такое отладчик и как это может помочь мне диагностировать проблемы?] (Http://stackoverflow.com/q/25385173/5221149) – Andreas

+1

У вас есть особая причина для использования 'date' и «Календарь», а не API-интерфейс java 8 time? –

ответ

1

Я думаю, что ваша проблема может быть вызвана граничным условием, которое приводит к добавлению одного дополнительного дня в каждый месяц до. Попытайтесь проверить день недели сначала, прежде чем увеличивать фактический день.

while (startCal.getTimeInMillis() <= endCal.getTimeInMillis()) { 
    if (startCal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY && 
     startCal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) { 

     workDays++; 
    } 

    startCal.add(Calendar.DAY_OF_MONTH, 1); 
} 
+0

Ваш код исправляет проблему, но ваше описание вводит в заблуждение, по крайней мере, так, как я его читал. Он не изменяется от 'do {} while()' to 'while() {}', который исправляет проблему, он перемещает вызов 'add()' в конец цикла, который это делает. С другой стороны, это не проверка * цикла *, которая должна быть до * приращения *, это * проверка на день недели *, которая должна быть до приращения. – Andreas

+0

@ Andreas Да, я понял это перед вашим комментарием, и сейчас я обновляюсь. Спасибо, как всегда за вашу бдительность. –

-1

Заменить < = в ваше время, условия для <, как показано ниже -

while (startCal.getTimeInMillis() < endCal.getTimeInMillis()); 

Это создает проблему, потому что в последний день месяца, ваше состояние (первоначально с < =) возвращает true, потому что, наконец, после увеличения значения startCal на 1 день он становится равным endCal в точке. Из-за того, чтобы стать равным, ваша следующая строка запускается на выполнение в сделай

startCal.add(Calendar.DAY_OF_MONTH, 1); 

и, таким образом, следующая дата первого апреля, который является понедельник. И таким образом это добавляется и в список рабочих дней.

ПРИМЕЧАНИЕ. Следуйте за комментарием @Andreas для отладки кода. С небольшой отладкой вы могли бы легко найти проблему. И снова отладка кода очень важна для разработчиков. Вы не можете просто игнорировать его!

Как верно указано @Andreas, 1-й день месяца также не будет проверен. Для того, чтобы проверить, 1-й день, вам нужно сравнить 1-ый день первого, а затем увеличиваем день на 1. ниже код -

do 
    { 
     if (startCal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY && startCal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) 
     { 
      workDays++; 
     } 
     startCal.add(Calendar.DAY_OF_MONTH, 1); //Moved this line to last of do block 
    } 
    while (startCal.getTimeInMillis() < endCal.getTimeInMillis()); 
+0

Не единственная проблема, потому что код не проверяет первый день месяца. – Andreas

+0

@ Андреас - Вы правы. Я обновлю ответ. – Manish

0

Используйте этот кусок кода, просто запустите цикл, пока условие startCal after endCal return false.

while(!startCal.after(endCal)) { 
     if (startCal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY && startCal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) { 
     workDays++; 
     } 
     startCal.add(Calendar.DATE, 1); 
    } 
3

Если добавить следующую строку после if заявления, вы увидите вашу проблему.

System.out.printf("%s %d%n", new SimpleDateFormat("yyyy-MM-dd EEE").format(startCal.getTime()), workDays); 

BTW: Это называется отладки.

Выход

2016-07-02 Sat 0 
2016-07-03 Sun 1 
2016-07-04 Mon 2 
2016-07-05 Tue 3 
2016-07-06 Wed 4 
2016-07-07 Thu 5 
2016-07-08 Fri 5 
2016-07-09 Sat 5 
2016-07-10 Sun 6 
2016-07-11 Mon 7 
2016-07-12 Tue 8 
2016-07-13 Wed 9 
2016-07-14 Thu 10 
2016-07-15 Fri 10 
2016-07-16 Sat 10 
2016-07-17 Sun 11 
2016-07-18 Mon 12 
2016-07-19 Tue 13 
2016-07-20 Wed 14 
2016-07-21 Thu 15 
2016-07-22 Fri 15 
2016-07-23 Sat 15 
2016-07-24 Sun 16 
2016-07-25 Mon 17 
2016-07-26 Tue 18 
2016-07-27 Wed 19 
2016-07-28 Thu 20 
2016-07-29 Fri 20 
2016-07-30 Sat 20 
2016-07-31 Sun 21 
2016-08-01 Mon 22 
22 

Как вы можете видеть, у вас есть две проблемы:

  • Первый день месяца (2016-07-01) не проверяется
  • первый день следующего месяца (2016-08-01) проверяется

Я буду лечить дайте ему вам понять решение. Удачи.

1
Calendar cal = Calendar.getInstance(); 
/* set the 1st date of ongoing month */ 
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), 1, 0, 0, 1); 
Calendar cal1 = Calendar.getInstance(); 
/* set the last date of ongoing month */ 
cal1.set(cal1.get(Calendar.YEAR), cal1.get(Calendar.MONTH), cal1.getMaximum(Calendar.DAY_OF_MONTH), 23, 59, 59); 
int workingDays = 0; 
/* run the while loop until the months are same */ 
while (cal.get(Calendar.MONTH) != cal1.get(Calendar.MONTH)) { 
     if (cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY 
      && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY) { 
       System.out.println("Check >> "+ cal.getTime()); 
       workingDays++; 
     } 
     cal.add(Calendar.DAY_OF_MONTH, 1); 
} 
System.out.println(workingDays);