io.slink.datetime.duration.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of slink-zero Show documentation
Show all versions of slink-zero Show documentation
Zero dependenices library to boost your Kotlin development
The newest version!
package io.slink.datetime
import kotlin.math.absoluteValue
import kotlin.time.*
internal val REGEX_DURATION = """
^-?(
(
((?\d+)d)?(\s*)
((?(0*(2[0-3]|[0-1]?[0-9])))h)?(\s*)
((?(0*([0-5]?[0-9])))m)?(\s*)
((?(0*([0-5]?[0-9])))s)?(\s*)
((?(0*([0-9]|[1-9][0-9]|[1-9][0-9][0-9])))ms)?
)
| (
((?\d+)d)
|((?\d+)h)
|((?\d+)m)
|((?\d+)s)
|((?\d+)ms)
)
)$
""".replace("\\s+".toRegex(), "")
.trim()
.toRegex()
internal const val MS = 1L
internal const val SEC = 1000 * MS
internal const val MIN = 60 * SEC
internal const val HOUR = 60 * MIN
internal const val DAY = 24 * HOUR
internal val GROUP_UNIT_CONVERTERS = mapOf(
"days" to DAY,
"hours" to HOUR,
"minutes" to MIN,
"seconds" to SEC,
"milliseconds" to MS,
"days2" to DAY,
"hours2" to HOUR,
"minutes2" to MIN,
"seconds2" to SEC,
"milliseconds2" to MS
)
fun String.toJavaDuration(): java.time.Duration? {
return this.toDuration()?.toJavaDuration()
}
fun String.toDuration(): Duration? {
val matcher = REGEX_DURATION.find(this) ?: return null
var durationMs = 0L
GROUP_UNIT_CONVERTERS.forEach { (groupName, multiplier) ->
val amount = (matcher.groups as MatchNamedGroupCollection)[groupName]?.value?.toLong()
if (amount != null)
durationMs += amount * multiplier
}
if (this.startsWith('-')) {
durationMs = -durationMs
}
return durationMs.toDuration(DurationUnit.MILLISECONDS)
}
fun java.time.Duration.humanReadableString(): String {
return this.toKotlinDuration().humanReadableString()
}
fun Duration.humanReadableString(): String {
val millisValue = this.inWholeMilliseconds.absoluteValue
if (millisValue == 0L) {
return "0ms"
}
val days = millisValue / DAY
var remainderD = millisValue - days * DAY
val hours = remainderD / HOUR
var remainderH = remainderD - hours * HOUR
val minutes = remainderH / MIN
val remainderM = remainderH - minutes * MIN
val seconds = remainderM / SEC
val remainderS = remainderM - seconds * SEC
val milliseconds = remainderS / MS
val elements = listOf("${days}d", "${hours}h", "${minutes}m", "${seconds}s", "${milliseconds}ms")
val start = elements.indexOfFirst { it[0] != '0' }
val end = elements.indexOfLast { it[0] != '0' }
val string = elements.subList(start, end + 1).joinToString(" ")
return if (this.isNegative()) {
"-$string"
} else {
string
}
}