2017-06-30 7 views
1

Calendarを使用してAndroid 7(API 24/25)で異常な動作が発生しました。Android 7.x(API24)WEEK_OF_MONTHカレンダーバグ?

を考えると、この非常に単純なコード:

SimpleDateFormat month_date = new SimpleDateFormat("dd.MM.YYYY"); 
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); 
cal.setFirstDayOfWeek(Calendar.MONDAY); 

for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) { 
    Calendar start = ((Calendar) cal.clone()); 
    start.set(2017, month, 1); 

    Calendar end = ((Calendar) start.clone()); 
    end.set(Calendar.DAY_OF_MONTH, end.getActualMaximum(Calendar.DAY_OF_MONTH)); 

    Log.d("CAL", "\n Date Start: " + month_date.format(start.getTime()) + " " + 
     " WEEK_OF_MONTH: " + start.get(Calendar.WEEK_OF_MONTH) 
    ); 
    Log.d("CAL", "\n Date End: " + month_date.format(end.getTime()) + 
     " WEEK_OF_MONTH: " + end.get(Calendar.WEEK_OF_MONTH) 
     ); 
} 

WEEK_OF_MONTHのための右の値を示すのAndroid 4.0xを、5.xおよび6.xの上で実行:

Date Start: 01.01.2016 WEEK_OF_MONTH: 1 
Date End: 31.01.2017 WEEK_OF_MONTH: 6 
Date Start: 01.02.2017 WEEK_OF_MONTH: 1 
Date End: 28.02.2017 WEEK_OF_MONTH: 5 
Date Start: 01.03.2017 WEEK_OF_MONTH: 1 
Date End: 31.03.2017 WEEK_OF_MONTH: 5 
Date Start: 01.04.2017 WEEK_OF_MONTH: 1 
Date End: 30.04.2017 WEEK_OF_MONTH: 5 
Date Start: 01.05.2017 WEEK_OF_MONTH: 1 
Date End: 31.05.2017 WEEK_OF_MONTH: 5 
Date Start: 01.06.2017 WEEK_OF_MONTH: 1 
Date End: 30.06.2017 WEEK_OF_MONTH: 5 
Date Start: 01.07.2017 WEEK_OF_MONTH: 1 
Date End: 31.07.2017 WEEK_OF_MONTH: 6 
Date Start: 01.08.2017 WEEK_OF_MONTH: 1 
Date End: 31.08.2017 WEEK_OF_MONTH: 5 
Date Start: 01.09.2017 WEEK_OF_MONTH: 1 
Date End: 30.09.2017 WEEK_OF_MONTH: 5 
Date Start: 01.10.2017 WEEK_OF_MONTH: 1 
Date End: 31.10.2017 WEEK_OF_MONTH: 6 
Date Start: 01.11.2017 WEEK_OF_MONTH: 1 
Date End: 30.11.2017 WEEK_OF_MONTH: 5 
Date Start: 01.12.2017 WEEK_OF_MONTH: 1 
Date End: 31.12.2017 WEEK_OF_MONTH: 5 

のAndroid 7.xの上で実行します破損したWEEK_OF_MONTH

Date Start: 01.01.2016 WEEK_OF_MONTH: 0 
Date End: 31.01.2017 WEEK_OF_MONTH: 5 
Date Start: 01.02.2017 WEEK_OF_MONTH: 1 
Date End: 28.02.2017 WEEK_OF_MONTH: 5 
Date Start: 01.03.2017 WEEK_OF_MONTH: 1 
Date End: 31.03.2017 WEEK_OF_MONTH: 5 
Date Start: 01.04.2017 WEEK_OF_MONTH: 0 
Date End: 30.04.2017 WEEK_OF_MONTH: 4 
Date Start: 01.05.2017 WEEK_OF_MONTH: 1 
Date End: 31.05.2017 WEEK_OF_MONTH: 5 
Date Start: 01.06.2017 WEEK_OF_MONTH: 1 
Date End: 30.06.2017 WEEK_OF_MONTH: 5 
Date Start: 01.07.2017 WEEK_OF_MONTH: 0 
Date End: 31.07.2017 WEEK_OF_MONTH: 5 
Date Start: 01.08.2017 WEEK_OF_MONTH: 1 
Date End: 31.08.2017 WEEK_OF_MONTH: 5 
Date Start: 01.09.2017 WEEK_OF_MONTH: 0 
Date End: 30.09.2017 WEEK_OF_MONTH: 4 
Date Start: 01.10.2017 WEEK_OF_MONTH: 0 
Date End: 31.10.2017 WEEK_OF_MONTH: 5 
Date Start: 01.11.2017 WEEK_OF_MONTH: 1 
Date End: 30.11.2017 WEEK_OF_MONTH: 5 
Date Start: 01.12.2017 WEEK_OF_MONTH: 0 
Date End: 31.12.2017 WEEK_OF_MONTH: 4 

ドキュメントが見つかりませんでしたAPI24のCalendarにハングアップします。

どのようにこの問題を解決するには?

すでにWEEK_OF_MONTHはAndroid 6.xと同じ値を返しますが、外見ではset(WEEK_OF_MONTH)も壊れています。 Jodaを使用してコードを書き直すことは選択できません。

答えて

0

あなたはchange how the weeks are countedsetMinimalDaysInFirstWeek()メソッドを使用することができます。

Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("Europe/Berlin"), Locale.GERMANY); 
cal.setFirstDayOfWeek(Calendar.MONDAY); 
cal.setMinimalDaysInFirstWeek(1); 

これは、月の週の正しい値を生成します。


あなたは、コードをJoda-Timeで書き直すことはオプションではないと言いましたが、別のAPIはどうですか?

Androidの場合、ThreeTenABP(詳しくはhere)と一緒に、Java 8の新しい日付/時刻クラスには、偉大なバックポートThreeTen Backportを使用できます。

ところで、Joda-Timeはメンテナンスモードで、新しいAPIに置き換えられているので、新しいプロジェクトを開始することはお勧めしません。 joda's websiteでも、"Joda-Timeは主に完成したプロジェクトとみなされていることに注意してください.Java SE 8を使用している場合は、java.time(JSR-310)に移行してください。

以下のクラスはorg.threeten.bpパッケージの下にあります。コードは次のようになります。

import java.util.Locale; 
import org.threeten.bp.DayOfWeek; 
import org.threeten.bp.LocalDate; 
import org.threeten.bp.Month; 
import org.threeten.bp.format.DateTimeFormatter; 
import org.threeten.bp.format.DateTimeFormatterBuilder; 
import org.threeten.bp.temporal.TemporalAdjusters; 
import org.threeten.bp.temporal.WeekFields; 

DateTimeFormatter fmt = new DateTimeFormatterBuilder() 
    // day and month 
    .appendPattern("dd.MM.") 
    // week based year (equivalent to YYYY in SimpleDateFormat) 
    .appendValue(WeekFields.ISO.weekBasedYear()) 
    // create formatter 
    .toFormatter(Locale.GERMANY); 

// week starting at monday, consider week=1 even if it has 1 day (default is 4) 
WeekFields wf = WeekFields.of(DayOfWeek.MONDAY, 1); 
for (Month month : Month.values()) { 
    LocalDate start = LocalDate.of(2017, month, 1); 
    LocalDate end = start.with(TemporalAdjusters.lastDayOfMonth()); 

    System.out.println("Date Start: " + fmt.format(start) + " " + " WEEK_OF_MONTH: " + start.get(wf.weekOfMonth())); 
    System.out.println("Date End: " + fmt.format(end) + " WEEK_OF_MONTH: " + end.get(wf.weekOfMonth())); 
} 

出力は次のようになります。

Date Start: 01.01.2016 WEEK_OF_MONTH: 1 
Date End: 31.01.2017 WEEK_OF_MONTH: 6 
Date Start: 01.02.2017 WEEK_OF_MONTH: 1 
Date End: 28.02.2017 WEEK_OF_MONTH: 5 
Date Start: 01.03.2017 WEEK_OF_MONTH: 1 
Date End: 31.03.2017 WEEK_OF_MONTH: 5 
Date Start: 01.04.2017 WEEK_OF_MONTH: 1 
Date End: 30.04.2017 WEEK_OF_MONTH: 5 
Date Start: 01.05.2017 WEEK_OF_MONTH: 1 
Date End: 31.05.2017 WEEK_OF_MONTH: 5 
Date Start: 01.06.2017 WEEK_OF_MONTH: 1 
Date End: 30.06.2017 WEEK_OF_MONTH: 5 
Date Start: 01.07.2017 WEEK_OF_MONTH: 1 
Date End: 31.07.2017 WEEK_OF_MONTH: 6 
Date Start: 01.08.2017 WEEK_OF_MONTH: 1 
Date End: 31.08.2017 WEEK_OF_MONTH: 5 
Date Start: 01.09.2017 WEEK_OF_MONTH: 1 
Date End: 30.09.2017 WEEK_OF_MONTH: 5 
Date Start: 01.10.2017 WEEK_OF_MONTH: 1 
Date End: 31.10.2017 WEEK_OF_MONTH: 6 
Date Start: 01.11.2017 WEEK_OF_MONTH: 1 
Date End: 30.11.2017 WEEK_OF_MONTH: 5 
Date Start: 01.12.2017 WEEK_OF_MONTH: 1 
Date End: 31.12.2017 WEEK_OF_MONTH: 5 
+1

これは素晴らしい、私の問題を修正しました!ありがとう:) – TheMenace

関連する問題