Освой Kotlin играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
В Kotlin 1.6.0 появился новый класс для работы с продолжительностью времени. По сути нас избавили от работы по вычислению количества секунд в часе, часов в сутках с перерывом на обед и сон (актуально для котов).
Для начала определим, как выглядят "три счастливых дня было у меня". Когда будете писать код вручную, студия предложит два варианта для импорта. Нужно выбрать правильную опцию.
import kotlin.time.Duration.Companion.days
val daysNumber = 3.days
Log.i("Duration", "$daysNumber") // 3d
Число 3 трансформировалось в непонятное 3d. Это объект класса Duration.
Допустим, мы хотим узнать, а сколько часов содержится в этих трёх счастливых днях.
val daysNumber = 3.days
val threeDayInHours = daysNumber.inWholeHours
Log.i("Duration", "$threeDayInHours") // 72
Свойство inWholeHours быстро покажет результат в часах. Также есть аналогичные свойства inWholeMinutes, inWholeSeconds, inWholeMilliseconds и т.д. для минут, секунд, миллисекунд.
Попробуем теперь вычислить, сколько часов в день кот занимается программированием. Не забываем, что коту нужно поспать, поесть и поиграть.
val sleepHours = 16.hours
val eatHours = 3.hours
val playHours = 5.hours
val codeHours = (1.days - sleepHours - eatHours - playHours).inWholeHours
Log.i("Duration", "$codeHours") // 0
Так и знал, кот тот ещё программист. В этом примере мы из дня вычитали часы, Duration сам вычислит все значения.
Экспериментальная функция convert() позволяет конвертировать одни единицы времени в другие. Достаточно указать значение и нужные единицы.
Опять для примера возьмём три дня. Указываем число 3.0, исходные единицы времени - день, желаемые единицы времени - час.
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
val convertedValue = Duration.convert(
value = 3.0,
sourceUnit = DurationUnit.DAYS,
targetUnit = DurationUnit.HOURS
)
Log.i("Duration", "$convertedValue")
Также существуют функции парсинга строк, содержащих даты в определённом ISO-формате.
val isoDuration = Duration.parse(value = "P1DT2H3M4.058S")
Log.i("Duration", "$isoDuration") // 1d 2h 3m 4.058s
Функция parse() может работать и с обычными строками. Если вы точно знаете, что у вас ISO-формат, то можете вызвать специальную функцию parseIsoString().
val isoDuration = Duration.parseIsoString("PT74H15M8S")
Log.i("Duration", "$isoDuration") // 1d 2h 3m 4.058s
Конечно, хочется из полученной строки извлечь отдельные данные о часах, минутах, секундах. Нет проблем, вызываем функцию toComponents().
val isoDuration = Duration.parseIsoString("PT74H15M8S")
.toComponents{
hours, minutes, seconds, _ ->
Log.i("Duration", "$hours, $minutes, $seconds") // 74, 15, 8
}
Можно произвести операцию в обратном порядке и получить строку в ISO-формате.
val isoDuration = (3.days + 2.hours + 15.minutes + 8.seconds).toIsoString()
Log.i("Duration", "$isoDuration") // PT74H15M8S