Frage

ich an einem Projekt arbeite, wo die Anforderung ein Datum als den letzten Freitag eines Monats berechnet zu haben ist. Ich denke, dass ich eine Lösung, die nur Standard-Java verwendet, aber ich frage mich, ob jemand etwas prägnanten oder effizient kannte. Unten ist das, was ich mit diesem Jahr getestet:

    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());
    }
War es hilfreich?

Lösung

Basierend auf marked23 der Vorschlag:

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

Andere Tipps

Lassen Sie Calendar.class tun, um seine Magie für Sie;)

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

Sie müssen nie Schleife, dies herauszufinden. Für das „letzten Freitag“ Datum für diesen Monat zu bestimmen, beginnen Sie mit dem ersten Tag des nächsten Monats. Subtrahieren Sie die entsprechende Anzahl der Tage, je nachdem, was (numerische) Tag der Woche der erste Tag des Monats fällt auf. Es ist dein „am vergangenen Freitag.“ Ich bin mir ziemlich sicher, dass es Einzeiler zu einem längeren eingekocht werden kann, aber ich bin kein Java-Entwickler. Also werde ich, dass jemand anderem überlassen.

java.time

Mit java.time Bibliothek in Java 8 gebaut und später, können Sie TemporalAdjusters.lastInMonth :

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

Sie können jeden Tag aus dem wählen DayOfWeek enum.

Wenn Sie Zeitinformationen hinzufügen möchten, können Sie eine beliebige verfügbar verwenden LocalDate LocalDateTime Umwandlung wie

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

würde ich eine Bibliothek verwenden, wie Jodatime . Es hat eine sehr nützliche API und verwendet normalen Monat Zahlen. Und das Beste von allem, es ist Thread-sicher.

Ich glaube, dass Sie eine Lösung mit (aber möglicherweise nicht die kürzeste, aber sicherlich besser lesbar) aufweisen kann:

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

Sie müssen zwei Dinge wissen - die Anzahl der Tage im Monat und den Wochentag der erste Tag des Monats fällt auf

.

Wenn der erste Tag des Monats ist ein

  • Sonntag, dann der letzte Freitag ist immer der 27..
  • Montag, dann der letzte Freitag ist immer der 26..
  • Dienstag, dann der letzte Freitag ist immer der 25..
  • Mittwoch, dann der letzte Freitag der 24. ist, es sei denn, es 31 Tage im Monat sind, dann ist es der 31.
  • Donnerstag, dann der letzte Freitag der 23. ist, es sei denn, es 30 Tage oder mehr im Monat, dann ist es der 30..
  • Freitag, den dann der letzte Freitag der 22. ist, es sei denn, es 29 Tage oder mehr im Monat, dann ist es die 29..
  • Samstag, dann der letzte Freitag ist immer der 28..

Es gibt nur drei Sonderfälle. Eine einzige Switch-Anweisung und drei if-Anweisungen (oder ternäre Operatoren, wenn Sie jeden Fall wie eine einzige Zeile haben ...)

es auf dem Papier funktioniert. Brauchen keine speziellen Bibliotheken, Funktionen, julian Umwandlungen, etc (na ja, außer den Wochentag zu bekommen die ersten auf fällt aus, und vielleicht die Anzahl der Tage in diesem Monat ...)

Aaron implementiert es in Java.

-Adam

Code für Adam Davis-Algorithmus

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

Obwohl ich mit scubabbl einverstanden ist, hier ist eine Version ohne Innen Weile.

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

Ein wenig leichter zu lesen, Brute-Force-Ansatz:

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

hier ist, wie der letzte Freitag zu bekommen, oder Wochentag auch immer, des Monats:

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.

Im Folgenden Programm ist für den letzten Freitag eines jeden Monats. es kann die letzten von jedem beliebigen Tag der Woche in einem Monat bekommen verwendet werden. Die variable offset=0 bedeutet aktuelle Monat (Systemdatum), Offset = 1 bedeutet, im nächsten Monat, so weiter. Die getLastFridayofMonth(int offset) Methode wird den am vergangenen Freitag zurück.

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
  }

}

In Java 8, können wir es einfach tun, wie:

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

Das sieht aus wie eine völlig akzeptable Lösung. Wenn das funktioniert, verwenden Sie es. Das ist minimal Code und es gibt keinen Grund, es zu optimieren, wenn Sie müssen.

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

Hope, das hilft ..

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top