如何截断Kotlin持续时间?

xytpbqjk  于 2023-08-06  发布在  Kotlin
关注(0)|答案(2)|浏览(117)

Java的Duration有a truncate function

Duration d = myDuration.truncatedTo(ChronoUnit.SECONDS);

字符串
第一个月
返回截断为指定单位的此Duration的副本。
截断持续时间将返回原始值的副本,其中概念字段小于设置为零的指定单位。例如,以MINUTES为单位进行截断将四舍五入到最接近的分钟,将秒和纳秒设置为零。
然而,Kotlin对Duration有一个不同的实现,它没有类似的截断方法。
我希望能够将Duration除以或乘以某个数字,然后(使用扩展函数)删除任何小于我提供的时间单位。

import kotlin.time.*
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes

fun main() {
   val duration = 10.days + 5.hours + 33.minutes
   println(duration)

   val divided = duration / 100.001
   println(divided)

   val truncatedToSeconds = divided.truncate(DurationUnit.SECONDS)
   println(truncatedToSeconds) // expect: 2h 27m 19s
   
   val truncatedToMinutes = divided.truncate(DurationUnit.MINUTES)
   println(truncatedToMinutes) // expect: 2h 27m

   val truncatedToHours = divided.truncate(DurationUnit.HOURS)
   println(truncatedToHours) // expect: 2h
}

fun Duration.truncate(unit: DurationUnit): Duration {
   /// ...
   return this
}

pxq42qpu

pxq42qpu1#

一种选择是将其转换为Long,然后使用所需的单位:

fun Duration.truncate(unit: DurationUnit): Duration =
    toLong(unit).toDuration(unit)

字符串

yebdmbv4

yebdmbv42#

这是一个纯Kotlin截断函数。
它使用Duration.toComponents()来获取持续时间的组成部分。然后,它将每个值转换回Duration,具体取决于它是否等于或大于请求的DurationUnit

import kotlin.time.*
import kotlin.time.DurationUnit.*
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.microseconds
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.Duration.Companion.seconds

/**
 * Truncates the duration to the specified [unit].
 *
 * Truncating the duration removes any time units smaller than the specified unit
 * and returns a new [Duration] with the truncated value.
 *
 * @param unit The duration unit to truncate to.
 * @returns a new [Duration] truncated to the specified [unit].
 */
private fun Duration.truncate(unit: DurationUnit): Duration {
  return toComponents { days: Long, hours: Int, minutes: Int, seconds: Int, nanoseconds: Int ->
    when (unit) {
      NANOSECONDS  -> this // there's no smaller unit than NANOSECONDS, so just return the current Duration
      MICROSECONDS -> days.days + hours.hours + minutes.minutes + seconds.seconds + nanoseconds.nanoseconds.inWholeMicroseconds.microseconds
      MILLISECONDS -> days.days + hours.hours + minutes.minutes + seconds.seconds + nanoseconds.nanoseconds.inWholeMilliseconds.milliseconds
      SECONDS      -> days.days + hours.hours + minutes.minutes + seconds.seconds
      MINUTES      -> days.days + hours.hours + minutes.minutes
      HOURS        -> days.days + hours.hours
      DAYS         -> days.days
    }
  }
}

字符串
备注:

  • nanosecondsis documented as being less than 1_000_000_000(1秒),因此无需将其转换为秒。
  • 为了将纳秒四舍五入到微秒,nanoseconds值首先转换为持续时间(nanoseconds.nanoseconds),然后四舍五入到微秒(inWholeMicroseconds),然后转换为持续时间(.microseconds)。使用相同的过程将纳秒四舍五入到毫秒。

示例

下面是一个使用示例,演示了truncate()函数应用于使用不同时间单位的持续时间。每次截断都会删除小于指定单位的所有时间单位。

import kotlin.time.*
import kotlin.time.DurationUnit.*
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.microseconds
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.Duration.Companion.seconds

fun main() {
  // create a duration
  val duration = 1.hours + 30.minutes + 45.seconds + 2.milliseconds + 3.microseconds + 5.nanoseconds
  println(duration)                        // 1h 30m 45.002003005s
  println(duration.truncate(NANOSECONDS))  // 1h 30m 45.002003005s (no truncation - can't go smaller than the smallest unit)
  println(duration.truncate(MICROSECONDS)) // 1h 30m 45.002003s    (no nanoseconds)
  println(duration.truncate(MILLISECONDS)) // 1h 30m 45.002s       (no milliseconds or nanoseconds)
  println(duration.truncate(SECONDS))      // 1h 30m 45s     (milliseconds and smaller are truncated)
  println(duration.truncate(MINUTES))      // 1h 30m         (seconds and smaller are truncated)
  println(duration.truncate(HOURS))        // 1h             (minutes and smaller are truncated)
  println(duration.truncate(DAYS))         // 0s             (all units are zeroed)
}
1h 30m 45.002003005s
1h 30m 45.002003005s
1h 30m 45.002003s
1h 30m 45.002s
1h 30m 45s
1h 30m
1h
0s

的数据
Run in Kotlin Playground

相关问题