2016-09-16 17 views
1

私のアプリケーションのローカルカレンダーを開発しています。これは毎月の繰り返しイベント(曜日)の問題です。月の第3金曜日を取得

私は、16-9-2016(16 SEP 2016 FRIDAY)で始まり、毎月第3金曜日のイベントを作成しています。来月には 金曜日14-10-2016金曜日に作成されます(これは問題です)。来月は第3金曜日になる。

私のコードは、私が問題を知っている

public Date nthWeekdayOfMonth(int dayOfWeek, int month, int year, int week, TimeZone timeZone) { 
     Calendar calendar = Calendar.getInstance(); 
     calendar.setTimeZone(timeZone); 
     calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek); 
     calendar.set(Calendar.WEEK_OF_MONTH, week); 
     calendar.set(Calendar.MONTH, month); 
     calendar.set(Calendar.YEAR, year); 
     return calendar.getTime(); 
    } 

です。しかし、私はそれを修正する方法を知りません..それを修正する方法はありますか?

+0

ヒント:可能であれば、good olカレンダーの代わりにJava8 Date/Time APIを使用してください。カレンダーはちょうど大きな時間です。 – GhostCat

+0

@GhostCat申し訳ありませんが、Java7を使用しています。 Java7カレンダーを使用して修正する方法はありますか –

+0

Java7を使用している場合は、[Joda Time](http://www.joda.org/joda-time/)と[この回答](http: //stackoverflow.com/questions/20527998/get-all-fridays-in-a-date-range-in-java)にはサンプルコードが含まれています。 – DVarga

答えて

3

コードは完全に正常に動作しているようですが、私が見ることができないものはありません。パラメータが間違っている可能性があります。

MONTHDAYがそのように、第三金曜日を取得するための0 = January0 = Sundayので、あなたのパラメータは次のようになります0-基づいていることに注意することが重要である:

次の出力を返します
nthWeekdayOfMonth(6, 9, 2016, 3, TimeZone.getTimeZone("Europe/London")); 

Fri Oct 21 11:06:33 BST 2016 

それを打破するには、次の

  1. 日曜日= 0
  2. 月は9であるため、週の日は、6である - すなわち10月
  3. 年は正常です - 2016
  4. 週は0ベースではないので、第3週は、インデックス3
  5. タイムゾーンになります通常通り

Calendar documentationを参照してください。何らかの理由でそうEDIT


それは私のマシンに動作しますが、それは他の人にはありません。私は、問題はそれに何ができるか知っているが、DAY_OF_WEEK_IN_MONTHを使用すると、このためのより良い選択肢であるように思われません。

public static Date nthWeekdayOfMonth(int dayOfWeek, int month, int year, int week, TimeZone timeZone) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.setTimeZone(timeZone); 
    calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek); 
    //calendar.set(Calendar.WEEK_OF_MONTH, week); 
    calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, week); 
    calendar.set(Calendar.MONTH, month); 
    calendar.set(Calendar.YEAR, year); 
    return calendar.getTime(); 
} 

うまく動作するはずです、私は通常GregorianCalendarが、Calendarを使用しています。

この(ほとんどの場合、うまくいきます)、私は他のマシンとideoneでテストしました。

+0

Fri Oct 14 20:16:10 IST 2016私は –

+0

を取得しています。私は理解していない... – px06

+0

私はjava7カレンダーを使用しています。およびタイムゾーンINDIANタイムゾーン(GMT +5:30) –

0

別のアプローチをとってください。月の最初の日が土曜日の場合、3番目の金曜日はその月の21日です。これを7日間延長してください:

  • 土曜日1日 - >金曜日21日。
  • 日曜日の第一 - >金曜日20日
  • 月曜日の第一 - >金曜日19
  • 火曜日第一 - >金曜日18
  • 水曜日第一 - >金曜日の17日
  • 木曜日第一 - >金曜日16日
  • 金曜日の第一 - >金曜日15日

月の初めの曜日を確認するだけです。

1

私は次の決定提案することができます:それは返す

System.out.println(nthWeekdayOfMonth(Calendar.FRIDAY, Calendar.SEPTEMBER, 2016, 3, TimeZone.getTimeZone("Europe/London"))); 
System.out.println(nthWeekdayOfMonth(Calendar.FRIDAY, Calendar.OCTOBER, 2016, 3, TimeZone.getTimeZone("Europe/London"))); 
System.out.println(nthWeekdayOfMonth(Calendar.FRIDAY, Calendar.NOVEMBER, 2016, 3, TimeZone.getTimeZone("Europe/London"))); 

:次のようにこれを行うための

Fri Sep 16 19:41:23 YEKT 2016 
Fri Oct 21 19:41:23 YEKT 2016 
Fri Nov 18 20:41:23 YEKT 2016 
+1

それは私のためにうまく動作します..ありがとう..私はほとんど変更を加えませんでした。 –

0

のJava 8の方法は次のとおりです。

LocalDate thirdFriday = LocalDate 
          .now() 
          .with(lastDayOfMonth()) 
          .with(previous(DayOfWeek.FRIDAY)).minusDays(7); 
ため

public Date nthWeekdayOfMonth(int dayOfWeek, int month, int year, int week, TimeZone timeZone) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.setTimeZone(timeZone); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.MONTH, month); 
    calendar.set(Calendar.DAY_OF_MONTH, 1); 
    // add +1 to week if first weekday of mounth > dayOfWeek 
    int localWeek = week; 
    if (calendar.get(calendar.DAY_OF_WEEK) > dayOfWeek) { 
     localWeek++; 
    } 
    calendar.set(Calendar.WEEK_OF_MONTH, localWeek); 
    calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek); 
    return calendar.getTime(); 
} 

0

これは機能しているJava 8の実装です。 KayVの例は2017年9月には機能しませんでしたが、正しい方向に向かうのに役立ちました。

import java.time.DayOfWeek; 
import java.time.LocalDate; 
import java.time.Month; 
import java.time.temporal.TemporalAdjusters; 
import java.util.List; 
import java.util.stream.Collectors; 
import java.util.stream.Stream; 

public class OptionExpirationDates { 

    public static void main(String[] args) { 

     LocalDate startDate = LocalDate.of(2017, Month.FEBRUARY, 15); 
     List<LocalDate> optionExDates = optionExpirationDates(startDate, 20); 

     for (LocalDate temp : optionExDates) { 
      System.out.println(temp); 
     } 
    } 

    public static List<LocalDate> optionExpirationDates(LocalDate startDate, int limit) { 
     return Stream.iterate(startDate, date -> date.plusDays(1)) 
       .map(LocalDate -> LocalDate.with(TemporalAdjusters.firstDayOfMonth()).minusDays(1) 
         .with(TemporalAdjusters.next(DayOfWeek.FRIDAY)).plusWeeks(2)) 
       .distinct() 
       .limit(limit) 
       .collect(Collectors.toList()); 
    } 
} 

おそらく、我々はまた、このコードは、検索エンジンがそれを拾うことができるように、オプションの有効期限を計算することであることを言及する必要があります。

関連する問題