尝试解析日期字符串时看到以下错误,有人可以指出正确的方向来解析此日期字符串吗?
"2019-01-22T12:43:01Z"
错误:
java.text.ParseException: Unparseable date: "2019-01-22T12:43:01Z"
代码:
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"
}
答案 0 :(得分:3)
由于您的输入不包含毫秒,因此可以删除模式中的:SS
:
const val SERVER_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"
我建议使用java.time
软件包。
答案 1 :(得分:3)
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)
}
让我们尝试一下:
fun main() {
println(timeSince("2019-01-22T12:43:01Z"))
}
这只是打印出来的:
236小时前
我正在使用java.time(现代Java日期和时间API)。与旧的类Date
相比,尤其是SimpleDateFormat
,我发现它更适合使用。如果传递给它的字符串不是ISO 8601格式,则上述方法将抛出DateTimeParseException
。对于大多数目的,这可能比返回0 h ago
更好。该方法可以容忍秒上存在和不存在(最多9个)小数,因此可以接受2019-01-22T12:43:01.654321Z
。
我们不需要格式化程序吗?不,我利用了您的字符串为ISO 8601格式的事实,这是现代日期和时间类将其默认解析(并打印)的格式。
ChronoUnit
和Instant
编辑:
我希望我可以使用ChronoUnit&Instant,但它需要Android的最低V26版本。我目前的下限是23。
java.time很好地工作在较旧的Android设备了。它只需要至少 Java 6 。
org.threeten.bp
导入日期和时间类。我看到两个代码错误在你的问题:
T
和Z
,由冒号分开,但你的串仅具有三个部分有。随着SimpleDateFormat
使用两个SS
的几分之一秒也是错误的,因为大写S
是毫秒,所以只有三个SSS
将使意义(相比之下,与现代{ {1}} DateTimeFormatter
仅用秒表示,因此任何数字(最多9 S
)才有意义。)SSSSSSSSS
当作文字。 UTC偏移量为零,需要进行这样的解析,否则您将获得错误的时间(在绝大多数JVM上)。Z
。java.time
。java.time
向Java 6和7(JSR-310的ThreeTen)的反向端口。答案 2 :(得分:0)
我来自服务器的原始值是:
2021-04-08T11:27:40.278Z
您可以简单地将其缩短。 使用 kotlin,2021 年:
// Read the value until the minutes only
val pattern = "yyyy-MM-dd'T'HH:mm"
val serverDateFormat = SimpleDateFormat(pattern, Locale.getDefault())
// Format the date output, as you wish to see, after we read the Date() value
val userPattern = "dd MMMM, HH:mm"
val userDateFormat = SimpleDateFormat(userPattern, Locale.getDefault())
val defaultDate = serverDateFormat.parse(INPUT_DATE_STRING)
if ( defaultDate != null ) {
val userDate = userDateFormat.format(defaultDate)
textView.text = userDate
}
结果:
<块引用>4 月 8 日,11:27