Question

Je travaille sur un projet dans lequel l'exigence est de faire en sorte que la date soit le dernier vendredi d'un mois donné. Je pense avoir une solution qui utilise uniquement Java standard, mais je me demandais si quelqu'un savait quelque chose de plus concis ou efficace. Voici ce que j'ai testé cette année:

    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());
    }
Était-ce utile?

La solution

D'après la suggestion de de mark23 :

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

Autres conseils

Laissez Calendar.class faire sa magie pour vous;)

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

Vous n'avez jamais besoin de faire une boucle pour le découvrir. Pour déterminer le " vendredi dernier " date de ce mois, commencez le premier jour du mois suivant. Soustrayez le nombre de jours approprié en fonction du jour (numérique) de la semaine sur lequel tombe le premier jour du mois. Il y a votre "vendredi dernier". Je suis sûr que ça peut être réduit à un long-courrier, mais je ne suis pas un développeur Java. Je vais donc laisser cela à quelqu'un d'autre.

java.time

Utilisation de java.time bibliothèque intégrée à Java 8 et versions ultérieures, vous pouvez utiliser TemporalAdjusters.lastInMonth :

val now = LocalDate.now() 
val lastInMonth = now.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY))

Vous pouvez choisir n'importe quel jour dans le DayOfWeek enum.

Si vous devez ajouter des informations sur l'heure, vous pouvez utiliser tout type LocalDate à LocalDateTime comme

lastFriday.atStartOfDay() // e.g. 2015-11-27T00:00

J'utiliserais une bibliothèque du type Jodatime . Il a une API très utile et utilise des nombres de mois normaux. Et le meilleur de tous, il est thread-safe.

Je pense que vous pouvez avoir une solution avec (mais peut-être pas la plus courte, mais certainement plus lisible):

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

Vous devez connaître deux choses: le nombre de jours dans le mois et le jour de la semaine du premier jour du mois.

Si le premier jour du mois est un

  • Dimanche, le dernier vendredi est toujours le 27.
  • Lundi, le dernier vendredi est toujours le 26.
  • Mardi, le dernier vendredi est toujours le 25.
  • Mercredi, le dernier vendredi est le 24, à moins qu'il n'y ait 31 jours dans le mois, alors c'est le 31
  • Jeudi, le dernier vendredi est le 23, à moins qu’il n’y ait 30 jours ou plus dans le mois, mais le 30.
  • Vendredi, le dernier vendredi est le 22, sauf si le mois a 29 jours ou plus, alors le 29.
  • Samedi, le dernier vendredi est toujours le 28.

Il n'y a que trois cas spéciaux. Une seule instruction switch et trois instructions if (ou des opérateurs ternaires si vous souhaitez que chaque cas ait une seule ligne ...)

Travaillez sur du papier. Pas besoin de bibliothèques spéciales, fonctions, conversions juliennes, etc. (enfin, sauf pour obtenir le jour de la semaine où tombe le premier jour, et peut-être le nombre de jours de ce mois ...)

Aaron l'a implémenté en Java.

-Adam

code pour algorithme d'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?");
}}

Bien que je sois d’accord avec scubabbl, voici une version sans contenu intérieur.

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

Légèrement plus facile à lire, approche par force brute:

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

voici comment obtenir le dernier vendredi ou le jour de la semaine du mois:

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.

Le programme ci-dessous concerne le dernier vendredi de chaque mois. il peut être utilisé pour obtenir le dernier jour de la semaine de chaque mois. La variable offset = 0 correspond au mois en cours (date système), offset = 1 correspond au mois suivant, etc. La méthode getLastFridayofMonth (int offset) renverra le dernier vendredi.

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
  }

}

En Java 8, nous pouvons le faire simplement comme suit:

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

Cela ressemble à une solution parfaitement acceptable. Si cela fonctionne, utilisez-le. C'est un code minimal et il n'y a aucune raison de l'optimiser à moins que vous n'ayez à le faire.

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

J'espère que cela vous aide ..

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);
  }
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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top