2012-11-12 3 views
1

Récemment, j'ai reçu un mail qui dit que décembre 2012 est un mois particulier. Ce mois-ci a cinq samedi (s), cinq dimanche (s) et cinq lundi (s). En outre, il dit que cela se produira une fois en 700 ans seulement. Donc, j'ai besoin de vérifier que dans les 2000 à 2100 combien de mois auront cinq samedis, dimanches et lundis respectivement. Est-ce que cela peut être réalisé par Java (en particulier en utilisant Calander API)?Java Calendar Date Check

Toute idée avec un exemple de code serait appréciable.

Merci.

Répondre

6

Pour un mois d'avoir 5 (samedi, dimanche, lundi), il doit:

  • ont 31 jours (4 semaines complètes et trois jours supplémentaires)
  • Démarrer un samedi (les trois jours à la fin doit être le cinquième samedi, dimanche, lundi)

Ces deux contrôles devraient être assez faciles même dans le java.util.Calendar fondamentalement cassé API. (Préférez Joda Time partout où vous avez le choix.) Si vous avez des problèmes pour implémenter l'un d'entre eux, vous devez publier un numéro spécifique, en nous indiquant jusqu'où vous vous trouvez.

+0

Il y a des mois qui ont 5 samedis avec moins de 31 jours. Aussi la règle de commencer un samedi n'est pas obligatoire aussi. Vois ma réponse. – dan

+1

Mais si le PO doit avoir tout le samedi..Lundi cinq fois alors les règles sont valides. – dan

1

S'il vous plaît vérifier le code ci-dessous:

/** 
* Print all the months which has five Mondays, Saturdays and Sundays 
* @param from year from 
* @param to year to 
*/ 
public void printMonths(int from, int to) { 
    List<String> monthList = new ArrayList<String>(); 
    for (int year =from; year<=to;year++) { 
     monthList.addAll(getMonth(year)); 
    } 

    for (String s : monthList) { 
     System.out.println(s); 
    } 
} 

/** 
* Get month with five sundays, saturdays and mondays 
* @param year 
* @return 
*/ 
private List<String> getMonth(int year) { 
    List<String> monthList = new ArrayList<String>(); 
    for (int month = 0; month < 12; month++) { 
     if (check(year, month)) { 
      monthList.add("" + year + "-" + (month+1)); 
     } 
    } 
    return monthList;  
} 

private boolean check(int year, int month) { 
    return checkFiveDays(year, month, 1) && checkFiveDays(year, month, 2) 
    && checkFiveDays(year, month, 7); 

} 

private boolean checkFiveDays(int year, int month, int dayOfWeek) { 
    Calendar c = Calendar.getInstance(); 
    c.set(year, month, 0, 0, 0, 0); 
    int times = 0; 
    do { 
     if (c.get(Calendar.DAY_OF_WEEK) == dayOfWeek) { 
      times++; 
     } 
     c.add(Calendar.DAY_OF_MONTH, 1); 
    } while (c.get(Calendar.MONTH)== month); 

    return times == 5; 
} 
-1

En fait, pendant un mois pour avoir 5 (samedi, dimanche ou lundi), il est pas nécessaire d'avoir 31 jours, voir Septembre 2012 (même Février sur certaines années bissextiles comme 2020 peut avoir 5 samedis). Pas même pour le mois pour commencer ce jour-là, voir: Mars 2013, pour le cas du samedi.
En utilisant Joda il est facile de compter tous ces cas, entre 2000 et 2100, comme:

DateTimeFormatter dateParser = DateTimeFormat.forPattern("yyyy");                
DateTime startDate = dateParser.parseDateTime("2000");                  
DateTime stopDate = dateParser.parseDateTime("2100");                   
DateTime date = startDate;                         
DateTime lastInMonth;                           
if (date.getDayOfWeek() != DateTimeConstants.SATURDAY)                  
    date = date.plusWeeks(1).withDayOfWeek(DateTimeConstants.SATURDAY);              
int count = 0;                            
while (date.isBefore(stopDate)) {                        
    if (date.getDayOfWeek() != DateTimeConstants.SATURDAY) //if it's not starting on Saturday         
     date = date.plusWeeks(1).withDayOfWeek(DateTimeConstants.SATURDAY); //jump to the first Saturday      
    lastInMonth = date.plusWeeks(4); //jump 4 weeks                   
    if (date.getMonthOfYear() == lastInMonth.plusDays(2).getMonthOfYear()) { //check if we are still on the same month  
     count++;                            
     // System.out.println("date = " + date); //uncomment to see each such month            
    }                               
    date = date.plusMonths(1); //advance a month                    
    date = date.withDayOfMonth(1); //start on the first day                 
}                                
System.out.println("Between " + startDate + " and " + stopDate + " there are " + count + " months that have five Saturdays"); 

once in some 700 years only il est pas tout à fait vrai, même si l'on ne compte que les mois de décembre.

+0

Pour avoir cinq samedis * et * cinq dimanches * et * cinq lundis, vous devez absolument avoir 31 jours dans le mois. C'est ce que la question exige. Votre code affiche juste un mois avec cinq samedis, ce qui n'est pas du tout la même chose. –

+0

@JonSkeet Parce que j'ai utilisé 'date.getMonthOfYear() == lastInMonth.plusDays (2) .getMonthOfYear()' il va vérifier si lundi prochain, après le cinquième samedi, est dans le même mois. – dan

+0

@JonSkeet Initialement, je ne comptais que le cas du 5 samedi, mais après avoir remarqué que l'utilisateur avait besoin de tous les cinq fois, j'ai mis à jour ma réponse. J'apprécierais que vous puissiez expliquer ce qui me manque, dans la mise en œuvre actuelle. – dan