java - 转换为 Calendar 对象

标签 java android

我在日历项目中工作并使用这个 Github 项目: https://github.com/wdullaer/MaterialDateTimePicker

我的日历可以正常工作,但我的要求是禁用所有工作日并仅启用周六和周日。

该库具有 datepickerdialog.setDisabledDays() 功能,我们必须在其中传递 Calendar[]

如果我将 Calendar.Monday 添加到数组(返回 int 值),它会抛出类似

的错误
setDisabledDays (java.util.Calendar[]) in DatePickerDialog cannot be applied to (int)

我主要尝试做的是,将所有工作日添加到 Calendar 数组中以禁用它们。那么,如何将 int 值转换为 Java 中的 Calendar 呢?

最佳答案

Yes @OleV.V. Any idea on how to do it?

是也不是。我会使用 ZonedDateTime 进行计算,这在您的 Android Java 7 中并不容易使用。如果您要在应用程序中使用日期和/或时间做更多工作和/或您预见维护在未来几年,您应该考虑使用 ThreeTen ABP 库。这为您提供了 JSR-310 中描述的日期和时间类。这些是用于 2017 年日期和时间的选项。另外,由于 Stack Overflow 应该是一个知识库,我将首先介绍这个选项,然后再介绍没有 JSR-310 的选项。

您询问要将什么传递给 setDisabledDays()。当我阅读您的链接时,您需要传递一个数组,其中包含不允许用户选择的所有日期。原则上是无限多天。因此,您首先需要确定用户真正需要选择一天到过去和/或 future 多长时间。然后强制用户在你的限制内,这样你就可以控制选择。接下来我觉得通过setSelectableDays来控制会容易很多。这将同时控制边界和星期几,并且星期六和星期日比工作日少,因此您需要一个更短的数组。

编辑:在我下面的代码中,我假设用户必须在 1 年 6 个月前到 future 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 上没有此方法。根据the docs感谢 Basil Bourque,您应该改为使用 DateTimeUtils.toGregorianCalendar(current)

今天在我的计算机上运行上面的代码 fragment 生成了一个包含 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() 来比较对象的身份。许多人花了很长时间来寻找由在字符串或其他对象之间使用 == 引起的错误。

关于java - 转换为 Calendar 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43981023/

相关文章:

java - 使用存储在列表中的变量评估 Java 中的 boolean 表达式

java - 调用 pop() 时堆栈返回错误的项目

android - PayPal MPL - 如何让用户选择金额?

android - 尺寸与屏幕密度有关吗?

android - 使用 RxJava2 PublishSubject 管理 null bool 值

java - Java 对象序列化问题

android - iOS 相当于 View.GONE

java - 在 Fragment 中实现 Spinner

java - 如何将 JSTL 标记的返回值返回到 EL 语句中?

JAVA,如何在 xml 中编辑节点内的文本?