SimpleDateFormat("dd/MM/yy kk:mm") 将时间显示为 24:30 而不是 00:30

SimpleDateFormat("dd/MM/yy kk:mm") showing time as 24:30 instead of 00:30

我必须将日期从 API 转换为 24 小时制,但 SimpleDateFormat("dd/MM/yy kk:mm") 显示的是 24:30 而不是 00:30.

我收到的日期格式为:“2020-05-25 10:34:27”

我正在按如下方式转换日期:

      val newDate: Date =  SimpleDateFormat("yyyy-MM-dd hh:mm:ss", 
    Locale.getDefault()).parse(vehiculos[b].fecha)
    val d = SimpleDateFormat("yyyy-MM-dd kk:mm", Locale.getDefault())
            .parse(SimpleDateFormat("yyyy-MM-dd HH:mm:ss", 
    Locale.getDefault()).format(newDate))
    val newFecha = SimpleDateFormat("dd/MM/yy kk:mm", Locale.getDefault()).format(d)

你应该使用大写字母K

SimpleDateFormat("dd/MM/yy KK:mm", Locale.getDefault())

k: Hour in day (1-24)

K: Hour in am/pm (0-11)

查看此站点进行测试:http://www.sdfonlinetester.info/

java.time

考虑使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。使用 java.time 将您的日期和时间保存在 LocalDateTime 对象中。 LocalDateTime 是一天中的日期和时间,没有与 UTC 的时区偏移量。您也可以考虑 ZonedDateTime,日期和时间 以及 时区。

当您收到来自 API 的字符串时,对其进行解析。我正在展示如何使用这个格式化程序来做到这一点:

private static final DateTimeFormatter API_PARSER
        = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE)
                .appendLiteral(' ')
                .append(DateTimeFormatter.ISO_LOCAL_TIME)
                .toFormatter(Locale.ROOT);

解析过程如下。为了演示,我花了一天中的时间 00 小时,这样我们就可以检查它们在格式化后是否显示为 24

    String fromApi = "2020-05-25 00:34:27";
    LocalDateTime dateTime = LocalDateTime.parse(fromApi, API_PARSER);
    System.out.println(dateTime);

此片段的输出是:

2020-05-25T00:34:27

只有当你需要给字符串输出时,比如给用户,把我们得到的LocalDateTime格式化成一个字符串。我们需要第二个格式化程序:

private static final DateTimeFormatter NEW_FORMATTER
        = DateTimeFormatter.ofPattern("dd/MM/yy HH:mm", Locale.ROOT);

有了它我们可以做到:

    String formattedDateTime = dateTime.format(NEW_FORMATTER);
    System.out.println(formattedDateTime);

25/05/20 00:34

我们得到了所需的 00 小时。

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

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

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

你做错了什么?

  • 在大多数情况下,尝试将日期和时间从一种字符串格式转换为另一种字符串格式是错误的方法。不要将日期和时间保留为字符串。保留适当的日期时间对象。例如 ZonedDateTimeLocalDateTime.
  • 您使用的是设计不良且过时已久的日期和时间 类 DateSimpleDateFormat
  • 你把事情搞得太复杂了。您从 String 转换为 Date,再转换为 String,再转换为 Date,最后一次转换为 String。你不可能需要所有这些,每一次操作都是一次出错的机会。
  • 正如其他人已经说过的,kk 用于 一天中的时钟时间 (1-24),这解释了为什么您没有得到 00 但是 24 在你最后一次转换中。在 java.time 中,大写 HH 表示一天中从 0023 的小时。
  • 不考虑时区可能是也可能不是错误。如果你知道服务器和用户在同一个时区,或者服务器知道用户的时区并按照相应的时间分发日期,你就可以了。如果服务器和用户使用不同的时区,则需要对您的日期和时间进行时区转换。

链接