我在Calendar Project中工作并使用这个Github项目: https://github.com/wdullaer/MaterialDateTimePicker
我的日历工作正常,但我的要求是禁用所有工作日,并且仅在星期六和星期日启用。
该库的功能为datepickerdialog.setDisabledDays()
,我们必须在其中传递Calendar[]
。
如果我将Calendar.Monday
添加到数组(返回int
值),则会引发错误,如
setDisabledDays (java.util.Calendar[]) in DatePickerDialog cannot be applied to (int)
我基本上尝试做的是,在Calendar
数组中添加所有工作日以禁用它们。那么,如何在Java中将int
值转换为Calendar
?
答案 0 :(得分:3)
是@ OleV.V。关于如何做的任何想法?
是和否。我会使用ZonedDateTime
进行计算,这在您的Android Java 7中并不常见。如果您打算在应用程序中更多地处理日期和/或时间和/或您预计将其保留在未来几年,您应该考虑使用ThreeTen ABP库。这为您提供了JSR-310中描述的日期和时间类。这些是2017年用于日期和时间的那些。另外因为Stack Overflow应该是一个知识库,我将首先提出这个选项,然后再提供没有JSR-310的选项。
您询问了传递给setDisabledDays()
的内容。在我阅读你的链接时,你需要传递一个数组,其中包含不允许用户选择的所有日期。原则上说这是无限多天。因此,您首先需要确定用户选择一天所需的过去和/或未来的距离。然后强制用户在限制范围内,以便您可以控制选择。接下来我认为通过setSelectableDays
来控制它要容易得多。这将控制一周的界限和星期几,星期六和星期日比平日更少,所以你需要一个更短的阵列。
编辑:在我的下面的代码中,我假设用户必须在从1年6个月前到未来1个月的时间范围内选择星期六或星期日。我相信你能为你设定正确的界限。
// start 1 year 6 months before today
// please change to the number of years, months, weeks and/or days you require
ZonedDateTime start = ZonedDateTime.now(ZoneId.systemDefault()).minusYears(1).minusMonths(6);
// end 1 month after today - also change to your own requirements
ZonedDateTime end = ZonedDateTime.now(ZoneId.systemDefault()).plusMonths(1);
List<Calendar> satsAndSuns = new ArrayList<>(200);
ZonedDateTime current = start;
if (current.getDayOfWeek().equals(DayOfWeek.SUNDAY)) {
satsAndSuns.add(GregorianCalendar.from(current));
}
current = current.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY));
while (! current.isAfter(end)) {
satsAndSuns.add(GregorianCalendar.from(current));
// add 1 day to get Sunday
current = current.plusDays(1);
assert current.getDayOfWeek().equals(DayOfWeek.SUNDAY);
if (current.isAfter(end)) {
break;
}
satsAndSuns.add(GregorianCalendar.from(current));
// add 6 days to get Saturday
current = current.plusDays(6);
assert current.getDayOfWeek().equals(DayOfWeek.SATURDAY);
}
Calendar[] selecatbleDays = satsAndSuns.toArray(new Calendar[satsAndSuns.size()]);
修改:我已使用GregorianCalendar.from(current)
将ZonedDateTime
转换为MaterialDateTimePicker所需的Calendar
对象。 Android上不存在此方法。根据{{3}}并感谢Basil Bourque,您应该使用DateTimeUtils.toGregorianCalendar(current)
。
今天在我的计算机上运行上面的代码片段,产生了一系列165 Calendar
个对象,整个星期六和星期日。
如果您不想依赖ThreeTen ABP,请使用此解决方案。要使用的算法与上面相同,只是细节不同:
Calendar end = new GregorianCalendar(TimeZone.getDefault());
end.add(Calendar.MONTH, 1);
List<Calendar> satsAndSuns = new ArrayList<>(200);
// start 1 year 6 months before today
Calendar current = new GregorianCalendar(TimeZone.getDefault());
current.add(Calendar.YEAR, -1);
current.add(Calendar.MONTH, -6);
if (current.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
// we need to add a copy because we will continue to modify current
// I really don’t like using clone(), but it’s the simplest way
satsAndSuns.add((Calendar) current.clone());
}
// Set current to next saturday
// This is where Calendar is not so straightforward as ZonedDateTime
// Subtraction of day of week works because in Calendar, Saturday is the last day of the week
current.add(Calendar.DATE, Calendar.SATURDAY - current.get(Calendar.DAY_OF_WEEK));
assert current.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY;
while (! current.after(end)) {
satsAndSuns.add((Calendar) current.clone());
current.add(Calendar.DATE, 1);
assert current.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
if (current.after(end)) {
break;
}
satsAndSuns.add((Calendar) current.clone());
current.add(Calendar.DATE, 6);
assert current.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY;
}
Calendar[] selecatbleDays = satsAndSuns.toArray(new Calendar[satsAndSuns.size()]);
带有枚举的.equals()
或==
编辑:这不是问题的一部分,但现在我们开始讨论它:我第一次使用current.getDayOfWeek() == DayOfWeek.SUNDAY
因为我发现它比.equals()
更容易阅读。它起作用,因为DayOfWeek
是一个枚举,JVM保证每个枚举常量只有一个实例。请在评论中找到异议。 Basil Bourque首先指导年轻程序员使用.equals()
来比较对象的身份。许多人长时间搜索在字符串或其他对象之间使用==
导致的错误。
答案 1 :(得分:0)
Calendar.Monday
只是int
而非Calendar
对象的常量。
从日历实施:
/**
* Value of the {@link #DAY_OF_WEEK} field indicating
* Monday.
*/
public final static int MONDAY = 2;