我正在使用 java.util.Calendar 使用其 set() 方法查找给定一周的开始。
这在 Android Nougat+ 上完美运行,但不适用于 Marshmallow 以下的任何 Android 版本。
我已经在物理设备和模拟器上进行了测试。
我已经使用调试器来验证问题出在日历代码上,而不是显示它的问题。
我使用 Kotlin 和 Java 创建了不同的最小示例,但问题仍然存在。
这是 Kotlin 的最小示例,其中 TextView 显示日期,而 Button 用于将该日期增加一周:
class MainActivity : AppCompatActivity() {
var week = 10
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Set TextView to show the date of the 10th week in 2018.
setCalendarText(week)
// Increase the week on every button click, and show the new date.
button.setOnClickListener { setCalendarText(++week) }
}
/**
* Set the text of a TextView, defined in XML, to the date of
* a given week in 2018.
*/
fun setCalendarText(week: Int) {
val cal = Calendar.getInstance().apply {
firstDayOfWeek = Calendar.MONDAY
set(Calendar.YEAR, 2018)
set(Calendar.WEEK_OF_YEAR, week)
set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 1)
}
textView.text = SimpleDateFormat("dd MMMM yyyy", Locale.UK).format(cal.time)
}
}
当按预期工作时,活动启动时 TextView 设置为显示“2018 年 3 月 5 日”。单击该按钮时,此值将更改为每个连续一周的第一天。
在 Android Marshmallow 及以下版本上:
- TextView 的初始值设置为本周的开始时间( 2018 年 9 月 3 日)。
- 单击按钮时日期不会更改。
- 如果日期设置为,日历可以正确检索当前一周的最后一天
Calendar.SUNDAY
。它不会在任何其他星期工作。
编辑:我试图创建一个 Java MVCE,它允许您通过运行快速检查基本问题是否出现CalendarTester.test()
。
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
class CalendarTester {
/**
* Check that the Calendar returns the correct date for
* the start of the 10th week of 2018 instead of returning
* the start of the current week.
*/
public static void test() {
// en_US on my machine, but should probably be en_GB.
String locale = Locale.getDefault().toString();
Log.v("CalendarTester", "The locale is " + locale);
Long startOfTenthWeek = getStartOfGivenWeek(10);
String startOfTenthWeekFormatted = formatDate(startOfTenthWeek);
boolean isCorrect = "05 March 2018".equals(startOfTenthWeekFormatted);
Log.v("CalendarTester", String.format("The calculated date is %s, which is %s",
startOfTenthWeekFormatted, isCorrect ? "CORRECT" : "WRONG"));
}
public static Long getStartOfGivenWeek(int week) {
Calendar cal = Calendar.getInstance();
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.set(Calendar.YEAR, 2018);
cal.set(Calendar.WEEK_OF_YEAR, week);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 1);
return cal.getTimeInMillis();
}
public static String formatDate(Long timeInMillis) {
return new SimpleDateFormat("dd MMMM yyyy", Locale.UK).format(timeInMillis);
}
}