Освой Kotlin играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Duration API

В 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
Реклама