日历 returns 错误的星期

Calendar returns wrong week

所以我需要获取本周星期一的时间(以毫秒为单位)和本周星期日的时间(以毫秒为单位),下面的代码工作正常,直到我在模拟器上安装了应用程序,如果我将时间设置为星期日,它 returns Jun 18 - Jun 24,但在三星 Galaxy s5 上它 returns Jun 11 - Jun 17 <- this is how it should show 我做错了什么吗?

getMondayTime 方法 returns 星期一的时间(以毫秒为单位)

private fun getMondayTime(): Long{
    val calendar = Calendar.getInstance()
    calendar.timeInMillis = System.currentTimeMillis()
    calendar.firstDayOfWeek = Calendar.MONDAY
    calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)
    calendar.set(Calendar.HOUR_OF_DAY, 0)
    calendar.set(Calendar.MINUTE, 0)
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)

    return calendar.timeInMillis
}

getSundayTime returns 周日的时间(以毫秒为单位)

private fun getSundayTime(): Long {
    val calendar = Calendar.getInstance()
    calendar.timeInMillis = System.currentTimeMillis()
    calendar.firstDayOfWeek = Calendar.MONDAY
    calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
    calendar.set(Calendar.HOUR_OF_DAY, 22)
    calendar.set(Calendar.MINUTE, 0)
    calendar.set(Calendar.SECOND, 0)
    calendar.set(Calendar.MILLISECOND, 0)

    return calendar.timeInMillis
}

在这里我把所有的时间都放在了地方

fun generateWeek(): Week{
    val format = SimpleDateFormat("MMM d", Locale.ENGLISH)
    val mondayTime = getMondayTime()
    val sundayTime = getSundayTime()

    val label = "${format.format(mondayTime)} - ${format.format(sundayTime)}"
    return Week(label, mondayTime, sundayTime)
}

java.time

很抱歉我不会写 Kotlin(如果那是你的语言?)所以我必须相信你 运行来自 Java 的名单。现代解决方案是:

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMM d", Locale.ENGLISH);
    // Time zone is crucial for controlling which week we get.
    ZoneId zone = ZoneId.of("America/Lower_Princes");
    WeekFields wf = WeekFields.ISO; // Monday is first day of week
    LocalDate today = LocalDate.now(zone);
    ZonedDateTime mondayTime = today.with(wf.dayOfWeek(), 1).atStartOfDay(zone);
    ZonedDateTime sundayTime = today.with(wf.dayOfWeek(), 7)
            .atTime(LocalTime.of(22, 0))
            .atZone(zone);
    String label = mondayTime.format(dateFormatter) + " - " + sundayTime.format(dateFormatter);
    System.out.println("Label:                 " + label);
    System.out.println("Monday time in millis: " + mondayTime.toInstant().toEpochMilli());
    System.out.println("Sunday time in millis: " + sundayTime.toInstant().toEpochMilli());

运行 刚才(星期一)打印了:

Label:                 Jun 18 - Jun 24
Monday time in millis: 1529294400000
Sunday time in millis: 1529892000000

在撰写本文时,在太平洋地区的极少数时区中仍然是星期日。所以我也尝试了其中之一:

    ZoneId zone = ZoneId.of("Pacific/Niue");

然后我上周得到:

Label:                 Jun 11 - Jun 17
Monday time in millis: 1528714800000
Sunday time in millis: 1529312400000

因此,指定正确的时区对于获得您想要的一周至关重要。我怀疑这是你问题中的问题:如果你的模拟器设置为使用一个时区,当你 运行 你的代码时它已经是星期一,正如你观察到的那样,它会给你接下来的一周。

我正在使用并推荐 java.time,现代 Java 日期和时间 API。

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

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

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

如果您反对依赖外部库,即使是像 ThreeTenABP 这样的面向未来的库——我的意思是,它是由为 Java 开发 java.time 的同一批人开发的,而且它仅包含的功能也将包含在核心 Java 中,一旦您升级到 API 级别 26 或更高 — 在这种情况下,您可以通过将正确的 TimeZone 对象传递给 Calendar.getInstance(TimeZone)方法(没试过)。 TimeZone 又是一个过时的日期和时间 类。

链接