首页 > 解决方案 > 日历在某些 Android 设备上返回糟糕的一周开始

问题描述

我想得到本周第一天的日期。所以我以这种方式实现了它:

fun getFirstDayInCurrentWeek(): Date {
    val calendar = Calendar.getInstance()
    calendar.clear(MILLISECOND)
    calendar.clear(SECOND)
    calendar.clear(MINUTE)
    calendar.set(HOUR_OF_DAY, 0)
    calendar.set(DAY_OF_WEEK, 1)
    return calendar.time
}

它适用于大多数设备,但有时它会返回下周第一天的日期。我不知道为什么。

课程来自java.util.*.

编辑:今天(28.05.2018)只需记录此函数的结果,您将看到 27.05.2018 或 03.06.2018。这些设备具有相同的语言环境和相同的时区。

标签: androiddatekotlindayofweekjava.util.calendar

解决方案


如果我理解正确,您想考虑星期天的第一天(如在美国)。

    WeekFields wf = WeekFields.SUNDAY_START;
    LocalDate today = LocalDate.now(ZoneId.of("Europe/Warsaw"));
    LocalDate firstDayOfThisWeek = today.with(wf.dayOfWeek(), 1);
    System.out.println(firstDayOfThisWeek);

我正在编写 Java 代码并相信您会转换为 Kotlin。今天(5 月 29 日,星期二)运行此打印

2018-05-27

相反,如果您希望将星期一作为一周的第一天(如波兰和国际标准所说),只需使用WeekFields.ISO而不是WeekFields.SUNDAY_START. 如果您希望它依赖于语言环境,请使用例如WeekFields.of(Locale.forLanguageTag("pl-PL")).

另一个可能更清晰的选择是:

    LocalDate firstDayOfThisWeek = today
            .with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));

在这两种情况下java.time,我都使用现代 Java 日期和时间 API。我认为这是一个很好的例子,它提供了更清晰的代码,与旧的日期和时间类(如Calendar.

你的代码出了什么问题?

据我了解文档,您的代码应该给出本周的星期日。Calendar星期天使用 1。您可能曾经calendar.set(DAY_OF_WEEK, SUNDAY)获得完全相同的信息。当我今天运行它时,当使用星期日作为一周的第一天时,我得到 5 月 27 日,当使用星期一作为第一天时,我得到 6 月 3 日(这意味着星期日是一周的最后一天)。但是,文档不是很清楚,而且Calendar课程可能会令人困惑。无论如何,当你在不同的设备上尝试时,可能也会发生这种情况:它们对周有不同的定义。如果您可以单独配置周定义,即使它们具有相同的语言环境,这也是可能的。

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time在较旧和较新的 Android 设备上运行良好。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及较新的 Android 设备(据我所知,从 API 级别 26 开始)中,现代 API 是内置的。
  • 在 Java 6 和 7 中获得 ThreeTen Backport,即新类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从org.threeten.bp子包中导入日期和时间类。

链接


推荐阅读