Kotlin 无法解析的日期 - ParseException 错误

pat*_*oid 2 java datetime date simpledateformat kotlin

我在尝试解析日期字符串时看到以下错误,有人能指出我解析这个日期字符串的正确方向吗?

"2019-01-22T12:43:01Z"
Run Code Online (Sandbox Code Playgroud)

错误:

java.text.ParseException: Unparseable date: "2019-01-22T12:43:01Z"
Run Code Online (Sandbox Code Playgroud)

代码:

package ch02.ex1_1_HelloWorld

import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.Locale
import java.util.Date
import java.util.concurrent.TimeUnit

const val SERVER_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss:SS'Z'" 
val sdf = SimpleDateFormat(SERVER_TIME_FORMAT, Locale.US)

fun main(args: Array<String>) {
    timeSince("2019-01-22T12:43:01Z")
}

fun timeSince(dateStr: String) {
    var diff : Long = 0
    try {
        diff = sdf.parse(dateStr).time - Date().time      
    } catch (e: Exception) {
        print(e)
    }
    "${TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS)} h ago"
} 
Run Code Online (Sandbox Code Playgroud)

孙兴斌*_*孙兴斌 5

由于您的输入不包含毫秒,您可以删除:SS模式中的:

const val SERVER_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'" 
Run Code Online (Sandbox Code Playgroud)

我建议使用java.timepackage.json 。


Ole*_*.V. 5

时间

import java.time.Instant;
import java.time.temporal.ChronoUnit;

fun timeSince(dateStr: String): String {
    val diffHours = ChronoUnit.HOURS.between(Instant.parse(dateStr), Instant.now())
    return "%d h ago".format(diffHours)
}
Run Code Online (Sandbox Code Playgroud)

让我们试试看:

fun main() {
    println(timeSince("2019-01-22T12:43:01Z"))
}
Run Code Online (Sandbox Code Playgroud)

这只是打印:

236 小时前

我正在使用 java.time,现代 Java 日期和时间 API。与旧课程相比,Date尤其是SimpleDateFormat我发现使用它要好得多。DateTimeParseException如果传递给它的字符串不是 ISO 8601 格式,则上述方法将抛出 a 。对于大多数目的,这可能比返回更好0 h ago。该方法可以容忍秒的存在和不存在(最多 9 个)小数,因此接受例如2019-01-22T12:43:01.654321Z.

我们不需要格式化程序吗?不。我正在利用您的字符串采用 ISO 8601 格式这一事实,现代日期和时间类将这种格式解析(并打印)为它们的默认格式。

我希望我可以使用ChronoUnitInstant

编辑:

我希望我可以使用 ChronoUnit & Instant,但它需要最低 V26 的 Android。我现在的最小值是 23。

java.time 也适用于较旧的 Android 设备。它只需要至少Java 6

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

你的代码出了什么问题?

我在您的问题中看到代码中有两个错误:

  1. 作为 ???????在这个答案中已经指出,您的格式需要 4 部分T和之间Z,用冒号分隔,但您的字符串只有三部分。随着SimpleDateFormat使用两个SS为几分之一秒也是错误的,因为大写S是毫秒,因此只有三个SSS才有意义(相比之下,与现代DateTimeFormatter S是几分之一秒,所以任何数(最多9 SSSSSSSSS)是有道理的)。
  2. Z将字符串中的 视为文字。这是一个 UTC 偏移量为零,需要这样解析,否则你会得到一个不正确的时间(在绝大多数 JVM 上)。

链接