为什么设置DAY_OF_WEEK重复闹钟如果今天是星期天不改日期?

Why set DAY_OF_WEEK for repeating alarm don't change date if today's Sunday?

我在 android 中使用 alarmmanager 为用户选择的日期设置重复闹钟,这很好用,但如果实际日期是星期天,则无法正常工作。让我们来看看。如果今天是星期日 (7),当我看到日历 toString() 时设置了星期一 (8) 和星期二 (9) 的闹钟,配置的日期是 7,请不要更改,但如果今天是另一天,它只能正常工作发生在今天星期天。

calendar.set(Calendar.HOUR_OF_DAY,h)
calendar.set(Calendar.MINUTE,m)
calendar.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY)//repeating for Monday if today is Sunday 8, and I set MONDAY, the new date most be Monday 9
Log.d("test",calendar.toString())

发生什么事了?

java.time 通过脱糖

考虑使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。

    LocalTime alarmTime = LocalTime.of(23, 45);
    ZonedDateTime alarmDateTime = ZonedDateTime.now(ZoneId.of("Africa/Porto-Novo"))
            .with(TemporalAdjusters.next(DayOfWeek.MONDAY))
            .with(alarmTime);
    
    System.out.println("Alarm date and time: " + alarmDateTime);

刚刚运行ning时(2月8日,星期一)的输出:

Alarm date and time: 2021-02-15T23:45+01:00[Africa/Porto-Novo]

如果您想让闹钟在今天就响起,请使用 nextOrSame() 而不是 next()

你的代码出了什么问题?

虽然程序员 运行 陷入 Calendar class 的许多困惑点之一是很常见的,但您 运行 陷入 其中两个

  1. calendar.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY) 可以将 Calendar 对象的日期设置为前一个或下一个星期一。它选择哪一个不仅取决于星期几,还取决于 Calendar 对象的设置,这些设置在不同的设备上通常会有所不同。
  2. 当您下次调用 calendar.toString() 时,您获得的字符串将不会反映更改星期后对 Calendar 对象所做的必要更改。我会立即期望星期几已经改变,但仍然会打印月份的旧值。我不会充分研究文档来给你一个准确的答案。在您调用 get() 或导致重新计算发生的其他指定方法之前,Calendar 不会计算其字段。

不使用 Calendar 的原因有很多。

问题:java.time 不需要 Android API 26 级吗?

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更高版本以及较新的 Android 设备(从 API 级别 26)中内置现代 API。
  • 在非Android Java 6 和 7 中获取 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接) .
  • 在较早的 Android 上使用脱糖或 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。在后一种情况下,请确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接