18

私は、特定の月の最終金曜日として日付を計算する必要があるプロジェクトに取り組んでいます。標準のJavaのみを使用するソリューションがあると思いますが、もっと簡潔で効率的なものを誰かが知っているかどうか疑問に思っていました. 以下は、私が今年テストしたものです。

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

16 に答える 16

37

Calendar.class に魔法をかけてもらいましょう ;)

pCal.set(GregorianCalendar.DAY_OF_WEEK,Calendar.FRIDAY);
pCal.set(GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1);
于 2010-03-30T13:49:33.870 に答える
27

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();
}
于 2008-09-16T21:04:14.677 に答える
15

java.time

Java 8 以降に組み込まれたjava.timeライブラリを使用すると、以下を使用できTemporalAdjusters.lastInMonthます。

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

DayOfWeek列挙から任意の日を選択できます。

時間情報を追加する必要がある場合は、次のような変換可能なLocalDateものを使用できますLocalDateTime

lastFriday.atStartOfDay() // e.g. 2015-11-27T00:00
于 2015-11-23T09:51:28.530 に答える
10

これを見つけるためにループする必要はありません。今月の「最終金曜日」の日付を決定するには、翌月の最初の日から開始します。月の最初の日が何の (数字の) 曜日に当たるかに応じて、適切な日数を引きます。あなたの「先週の金曜日」があります。長いワンライナーに要約できると確信していますが、私はJava開発者ではありません。だから、それは他の人に任せます。

于 2008-09-16T20:14:17.137 に答える
7

Jodatimeのようなライブラリを使用します。非常に便利な API を備えており、通常の月数を使用します。そして何よりも、スレッドセーフです。

私はあなたが解決策を持つことができると思います(しかし、おそらく最短ではありませんが、確かにより読みやすいです):

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);
于 2008-09-16T20:13:47.513 に答える
2

その月の最後の金曜日、または任意の曜日を取得する方法は次のとおりです。

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.
于 2011-10-18T10:55:03.150 に答える
2

2 つのことを知る必要があります。1 か月の日数と、その月の 1 日が当たる曜日です。

月の最初の日が

  • 日曜日の場合、最後の金曜日は常に27 日です。
  • 月曜日の場合、最後の金曜日は常に26 日です。
  • 火曜日の場合、最後の金曜日は常に25 日です。
  • 水曜日の場合、最後の金曜日は 24 日です。月に 31 日がない場合は 31 日です。
  • 木曜日の場合、最後の金曜日は 23 日です。月に 30 日以上ない場合は 30 日です。
  • 金曜日の場合、最後の金曜日は 22 日です。月に 29 日以上ない場合は 29 日です。
  • 土曜日の場合、最後の金曜日は常に28 日です。

特殊なケースは 3 つだけです。1 つの switch ステートメントと 3 つの if ステートメント (または、すべてのケースを 1 行にしたい場合は、三項演算子...)

紙の上でそれを解決します。特別なライブラリ、関数、ユリウス変換などは必要ありません (まあ、1 日が当たる曜日と、その月の日数を取得することを除いて...)

Aaron はそれを Java で実装しました。

-アダム

于 2008-09-16T20:36:58.037 に答える
2

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?");
}}
于 2008-09-16T21:27:28.007 に答える
1

以下のプログラムは、毎月最終金曜日です。任意の月の任意の曜日の最後を取得するために使用できます。変数offset=0は現在の月 (システム日付) を意味し、offset=1 は翌月を意味します。getLastFridayofMonth(int offset)メソッドは最後の金曜日を返します。

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
  }

}
于 2012-06-06T21:54:44.323 に答える
1

少し読みやすいブルート フォース アプローチ:

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;
}
于 2008-09-16T20:09:12.190 に答える
1

scubabbl に同意しますが、これは内部の while のないバージョンです。

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());
}
于 2008-09-16T20:15:11.723 に答える
0

お役に立てれば..

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);
  }
于 2009-07-01T07:19:00.857 に答える
0

それは完全に受け入れられる解決策のように見えます。それが機能する場合は、それを使用してください。これは最小限のコードであり、必要がない限り最適化する理由はありません。

于 2008-09-16T19:56:49.333 に答える
-1
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;
}
于 2012-02-27T17:22:59.023 に答える