当目标 Android API < 26 时,Duration.between 的最佳替代方案是什么?
What's the best alternative for Duration.between when targetting Android API < 26?
目前,我继续修补我的一个宠物项目的功能。
我决定包含阻止用户执行某些操作的功能 action/s 并显示横幅以显示冷却时间。
例如
鉴于:从 2019 年 11 月 19 日 2:00:00 上午 (1574128800) 到 2019 年 11 月 21 日 6:32:00 下午 (1574361120),用户因执行某些 action/s 而被阻止。
输出:2 days 16 hours 32 minutes
这就是我现在的方法。不幸的是,它只适用于 Android API >= 26.
/**
* If using for Android, `Duration` requires API > 26
* @param start Epoch time in milliseconds
* @param end Epoch time in milliseconds
*/
fun getReadableBetween(start: Long, end: Long): String {
val startDate = Date(start)
val endDate = Date(end)
var duration = Duration.between(startDate.toInstant(), endDate.toInstant())
val days = duration.toDays()
duration = duration.minusDays(days)
val hours = duration.toHours()
duration = duration.minusHours(hours)
val minutes = duration.toMinutes()
val stringBuilder = StringBuilder()
if (days != 0L) {
stringBuilder.append(days)
if (days == 1L) {
stringBuilder.append(" day ")
} else {
stringBuilder.append(" days ")
}
}
if (hours != 0L) {
stringBuilder.append(hours)
if (hours == 1L) {
stringBuilder.append(" hour ")
} else {
stringBuilder.append(" hours ")
}
}
if (minutes != 0L) {
stringBuilder.append(minutes)
if (minutes == 1L) {
stringBuilder.append(" minute.")
} else {
stringBuilder.append(" minutes.")
}
}
println("Breakdown:")
println("Days: $days")
println("Hours: $hours")
println("Minutes: $minutes")
return stringBuilder.toString()
}
尽管我很想使用 3rd 方库,但我想亲自动手使用开箱即用的日期和时间 API 基础知识。
PS。在将此链接到其他 SO 帖子之前,请考虑场景。
决定为 Android API < 26 创建遗留功能。
/**
* If using for Android & API < 26
* @param start Epoch time in milliseconds
* @param end Epoch time in milliseconds
*/
fun getReadableBetweenLegacy(start: Long, end: Long): String {
val startDate = Date(start)
val endDate = Date(end)
val calendar = Calendar.getInstance()
val diff = endDate.time - startDate.time
calendar.timeInMillis = diff
val daySeconds = 1000 * 60 * 60 * 24
val hourSeconds = 1000 * 60 * 60
val days = diff / daySeconds
val hours = ((diff - (daySeconds * days)) / (hourSeconds));
val minutes = (diff - (daySeconds * days) - (hourSeconds * hours)) / (1000 * 60)
val stringBuilder = StringBuilder()
if (days != 0L) {
stringBuilder.append(days)
if (days == 1L) {
stringBuilder.append(" day ")
} else {
stringBuilder.append(" days ")
}
}
if (hours != 0L) {
stringBuilder.append(hours)
if (hours == 1L) {
stringBuilder.append(" hour ")
} else {
stringBuilder.append(" hours ")
}
}
if (minutes != 0L) {
stringBuilder.append(minutes)
if (minutes == 1L) {
stringBuilder.append(" minute.")
} else {
stringBuilder.append(" minutes.")
}
}
println("Breakdown:")
println("Days: $days")
println("Hours: $hours")
println("Minutes: $minutes")
return stringBuilder.toString()
}
解决方案非常简单,几乎没有误差。
如果您使用的是 Gradle 插件 4.0 或更高版本(使用 Android Studio 4.0 或更高版本),您可以利用 D8 核心库脱糖。这包括 java.time
中的一部分功能,并允许您在项目中使用 java.time.Duration
;即使您需要支持早于 API 26.
的版本
在您模块的 build.gradle
文件中:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
}
// If using Kotlin
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
}
dependencies {
…
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}
您现在应该可以使用此 class 错误。
一些来源:
目前,我继续修补我的一个宠物项目的功能。 我决定包含阻止用户执行某些操作的功能 action/s 并显示横幅以显示冷却时间。
例如
鉴于:从 2019 年 11 月 19 日 2:00:00 上午 (1574128800) 到 2019 年 11 月 21 日 6:32:00 下午 (1574361120),用户因执行某些 action/s 而被阻止。
输出:2 days 16 hours 32 minutes
这就是我现在的方法。不幸的是,它只适用于 Android API >= 26.
/**
* If using for Android, `Duration` requires API > 26
* @param start Epoch time in milliseconds
* @param end Epoch time in milliseconds
*/
fun getReadableBetween(start: Long, end: Long): String {
val startDate = Date(start)
val endDate = Date(end)
var duration = Duration.between(startDate.toInstant(), endDate.toInstant())
val days = duration.toDays()
duration = duration.minusDays(days)
val hours = duration.toHours()
duration = duration.minusHours(hours)
val minutes = duration.toMinutes()
val stringBuilder = StringBuilder()
if (days != 0L) {
stringBuilder.append(days)
if (days == 1L) {
stringBuilder.append(" day ")
} else {
stringBuilder.append(" days ")
}
}
if (hours != 0L) {
stringBuilder.append(hours)
if (hours == 1L) {
stringBuilder.append(" hour ")
} else {
stringBuilder.append(" hours ")
}
}
if (minutes != 0L) {
stringBuilder.append(minutes)
if (minutes == 1L) {
stringBuilder.append(" minute.")
} else {
stringBuilder.append(" minutes.")
}
}
println("Breakdown:")
println("Days: $days")
println("Hours: $hours")
println("Minutes: $minutes")
return stringBuilder.toString()
}
尽管我很想使用 3rd 方库,但我想亲自动手使用开箱即用的日期和时间 API 基础知识。
PS。在将此链接到其他 SO 帖子之前,请考虑场景。
决定为 Android API < 26 创建遗留功能。
/**
* If using for Android & API < 26
* @param start Epoch time in milliseconds
* @param end Epoch time in milliseconds
*/
fun getReadableBetweenLegacy(start: Long, end: Long): String {
val startDate = Date(start)
val endDate = Date(end)
val calendar = Calendar.getInstance()
val diff = endDate.time - startDate.time
calendar.timeInMillis = diff
val daySeconds = 1000 * 60 * 60 * 24
val hourSeconds = 1000 * 60 * 60
val days = diff / daySeconds
val hours = ((diff - (daySeconds * days)) / (hourSeconds));
val minutes = (diff - (daySeconds * days) - (hourSeconds * hours)) / (1000 * 60)
val stringBuilder = StringBuilder()
if (days != 0L) {
stringBuilder.append(days)
if (days == 1L) {
stringBuilder.append(" day ")
} else {
stringBuilder.append(" days ")
}
}
if (hours != 0L) {
stringBuilder.append(hours)
if (hours == 1L) {
stringBuilder.append(" hour ")
} else {
stringBuilder.append(" hours ")
}
}
if (minutes != 0L) {
stringBuilder.append(minutes)
if (minutes == 1L) {
stringBuilder.append(" minute.")
} else {
stringBuilder.append(" minutes.")
}
}
println("Breakdown:")
println("Days: $days")
println("Hours: $hours")
println("Minutes: $minutes")
return stringBuilder.toString()
}
解决方案非常简单,几乎没有误差。
如果您使用的是 Gradle 插件 4.0 或更高版本(使用 Android Studio 4.0 或更高版本),您可以利用 D8 核心库脱糖。这包括 java.time
中的一部分功能,并允许您在项目中使用 java.time.Duration
;即使您需要支持早于 API 26.
在您模块的 build.gradle
文件中:
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
}
// If using Kotlin
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8
}
}
dependencies {
…
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}
您现在应该可以使用此 class 错误。
一些来源: