Duration — o que é, calcular a duração no Android

Autor: IT Sectr Publicado: 2026-07-13 Tempo de leitura: 9 min

Duration — uma classe imutável do pacote java.time que representa a duração entre dois momentos no tempo em segundos e nanossegundos. Duration mede quantidades de tempo baseadas em tempo — horas, minutos, segundos, milissegundos e nanossegundos. De acordo com a especificação da Oracle Java 17 (2024), ao contrário de Period (que mede anos-meses-dias), Duration trabalha com unidades de tempo precisas e não depende do calendário.

Pontos principais

  • Duration — uma classe imutável para medir duração em segundos e nanossegundos.
  • Ao contrário de Period, Duration trabalha com unidades baseadas em tempo (horas, minutos, segundos), não baseadas em data (dias, meses, anos).
  • Criada através de Duration.between(start, end), Duration.ofMinutes(), Duration.ofHours() e outros métodos de fábrica estáticos.
  • Suporta operações aritméticas: plus(), minus(), multipliedBy(), dividedBy(), negated().
  • Para desenvolvimento Android, Duration é útil para calcular timeouts, intervalos de sincronização e duração de operações.

O que é Duration?

Duration é uma classe que modela a quantidade de tempo em segundos e nanossegundos. Ela representa uma duração baseada em tempo, ou seja, um número físico de segundos não vinculado a um calendário. Duration pode ser pensada como “125 minutos” ou “2 horas 5 minutos” — ao contrário de Period, que diria “2 meses”.

A representação interna de Duration consiste em dois campos: long seconds (segundos) e int nanos (nanossegundos, de 0 a 999999999). O valor pode ser negativo — o que significa uma duração “para trás” no tempo. O valor máximo é ±31557014167219200 segundos.

De acordo com Baeldung (2024), Duration é uma classe chave para calcular duração de operações, configurar timeouts e medir desempenho. Duration é imutável e thread-safe, permitindo seu uso em ambientes multithread sem sincronização.

A classe implementa as interfaces Comparable, TemporalAmount e TemporalUnit. TemporalAmount permite usar Duration nos métodos plus/minus das classes LocalTime, LocalDateTime, Instant e ZonedDateTime.

Duration vs Period: qual é a diferença?

A principal diferença é que Duration mede o número exato de segundos (baseado em tempo), enquanto Period mede unidades de calendário (baseado em data): anos, meses, dias. Duration diz: “86400 segundos se passaram.” Period diz: “1 dia se passou.” A diferença torna-se aparente durante as mudanças de horário de verão — 1 dia em Period é sempre 1 dia de calendário, enquanto 86400 segundos em Duration podem corresponder a 23 ou 25 horas durante o DST.

Duration é usado para medir tempo físico: timeouts de conexão, tempo de execução de consultas, intervalos entre dois Instant. Period é usado para cálculos de calendário: idade de uma pessoa (Period.between(dateOfBirth, today)), duração de um contrato.

Duration trabalha com segundos e nanossegundos, portanto pode ser dividida em partes (horas, minutos). Period trabalha com anos, meses e dias — unidades de calendário indivisíveis. De acordo com o Oracle Java Tutorial (2024), a escolha entre Duration e Period depende do tipo de tarefa: tempo preciso vs datas de calendário.

Criar Duration

A forma mais comum é Duration.between(Temporal start, Temporal end). Temporal pode ser Instant, LocalTime, LocalDateTime, ZonedDateTime — qualquer tipo que implemente Temporal. O método retorna uma Duration representando a diferença start - end (pode ser negativa).

Métodos de fábrica estáticos: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Também existe of(long amount, TemporalUnit unit) para unidades arbitrárias — ChronoUnit.HOURS, ChronoUnit.MINUTES e outras.

O método parse(CharSequence) aceita uma string no formato ISO-8601: “PT1H30M” (1 hora 30 minutos), “PT45S” (45 segundos), “P2DT3H” (2 dias 3 horas). A string sempre começa com “PT” (Period of Time).

kotlin
val betweenMoments = Duration.between(
    Instant.parse("2026-07-21T10:00:00Z"),
    Instant.parse("2026-07-21T14:30:00Z")
)

val fromMinutes = Duration.ofMinutes(90)
val fromHours = Duration.ofHours(2)
val parsed = Duration.parse("PT1H30M")

Aritmética com Duration

Duration suporta um conjunto completo de operações aritméticas. Os métodos plus(Duration) e minus(Duration) adicionam ou subtraem outra duração. Os métodos plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — para adicionar unidades específicas.

Para multiplicação e divisão, use multipliedBy(long) e dividedBy(long). Duration.multipliedBy(2) duplica a duração. Duration.dividedBy(3) divide em três partes com arredondamento para baixo. O método negated() inverte o sinal — positivo torna-se negativo e vice-versa.

O método abs() retorna uma Duration com valor absoluto (positivo). isNegative() e isZero() são verificações. toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() convertem para as unidades correspondentes.

kotlin
val oneHour = Duration.ofHours(1)
val twoHours = oneHour.plus(Duration.ofMinutes(60))
val halfHour = oneHour.dividedBy(2)

val minutes = twoHours.toMinutes()
val absDuration = (Duration.ofHours(-1)).abs()

Comparar Duration

Duration implementa a interface Comparable, permitindo comparar durações naturalmente. O método compareTo() retorna um número negativo, zero ou positivo. isNegative() e isZero() são verificações rápidas. Para comparação explícita, use equals() — duas Duration são iguais se seus segundos e nanossegundos coincidirem.

Como Duration pode ser negativa, comparações “maior que” ou “menor que” funcionam considerando o sinal. -5 minutos é menor que 2 minutos. O método abs() é útil para comparar comprimentos “absolutos” independentemente da direção.

Em Kotlin, Duration suporta operadores de comparação através de sobrecarga de operadores: a < b, a > b, a <= b. Plus e minus também estão disponíveis como operadores: a + b, a - b.

kotlin
val short = Duration.ofMinutes(5)
val long = Duration.ofMinutes(10)

if (short < long) {
    Log.d("Duration", "5 min é menor que 10")
}

val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Negativo: ${negative.isNegative()}")

Duration em tarefas reais de Android

O primeiro exemplo é configurar a sincronização periódica com o servidor. Duration é usada para calcular o intervalo entre sincronizações e verificar se o limite de tempo sem atualização foi excedido.

kotlin
data class SyncConfig(
    val interval: Duration = Duration.ofMinutes(15),
    val retryDelay: Duration = Duration.ofSeconds(30)
)

fun calculateNextSync(
    lastSync: Instant,
    config: SyncConfig
): Duration {
    val elapsed = Duration.between(lastSync, Instant.now())
    return config.interval.minus(elapsed)
        .coerceAtLeast(Duration.ZERO)
}

O segundo exemplo é medir o tempo de execução de uma operação para registro de desempenho.

kotlin
fun measureExecution(
    tag: String,
    block: () -> Unit
) {
    val start = Instant.now()
    block()
    val duration = Duration.between(start, Instant.now())
    Log.d(tag, "Executado em ${duration.toMillis()} ms")
}

O terceiro exemplo é calcular o tempo restante de um temporizador (por exemplo, contagem regressiva até o fim de uma promoção).

kotlin
class CountdownTimer(
    private val expiresAt: Instant
) {
    fun getRemainingTime(): Duration {
        val remaining = Duration.between(
            Instant.now(), expiresAt
        )
        return remaining.coerceAtLeast(Duration.ZERO)
    }

    fun isExpired(): Boolean = getRemainingTime() == Duration.ZERO
}

Converter Duration para string

O método toString() retorna Duration no formato ISO-8601: “PT1H30M” (1 hora 30 minutos), “PT45.5S” (45.5 segundos). Este formato é conveniente para troca entre máquinas, mas não para exibição ao usuário.

Para formato legível por humanos, use toDays(), toHours(), toMinutes(), toSeconds() seguido de montagem manual da string. Por exemplo: “${days} d ${hours} h ${minutes} min”. Note que toHours() retorna o número total de horas, não as horas dentro do dia.

Para decompor Duration em componentes, use a fórmula: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. De acordo com Apache Commons Lang (2024), a biblioteca DurationFormatUtils fornece capacidades adicionais de formatação.

kotlin
fun formatDuration(duration: Duration): String {
    val hours = duration.toHours()
    val minutes = duration.toMinutes() % 60
    val seconds = duration.seconds % 60

    return buildString {
        if (hours > 0) append("${hours} h ")
        if (minutes > 0) append("${minutes} min ")
        append("${seconds} sec")
    }
}

Erros comuns

O primeiro erro é confundir Duration e Period ao trabalhar com datas. Duration mede segundos, portanto Duration.ofDays(1) é sempre 24 horas (86400 segundos), independentemente das mudanças de horário de verão. Se precisar de um dia de calendário, use Period.ofDays(1).

O segundo erro é perder nanossegundos durante a conversão. Duration pode armazenar nanossegundos, mas toMillis() e toSeconds() os descartam. Para cálculos precisos, use toNanos() ou trabalhe com Duration diretamente sem converter para primitivos.

O terceiro erro é ignorar Duration negativa. Duration.between(start, end) retorna start - end. Se start estiver depois de end, Duration será negativa. O método abs() ajuda a obter o valor absoluto, e isNegative() verifica a ordem dos argumentos.

O quarto erro é formatação incorreta de Duration para a interface do usuário. Duration.toString() retorna ISO-8601, que não é legível. Sempre formate Duration manualmente para exibição ao usuário usando toHours(), toMinutes() e toSeconds() com o resto correto da divisão.

Perguntas frequentes

Duration pode ser negativa?

Sim, Duration pode ser negativa. Duration.between(start, end) retorna start - end. Se start estiver depois de end, Duration será negativa. Use abs() para obter o valor absoluto ou isNegative() para verificar.

Como somar duas Duration?

Use o método plus(Duration) ou o operador + em Kotlin: duration1 + duration2. O resultado é uma nova Duration. O método minus(Duration) subtrai uma duração de outra. Todas as operações são imutáveis e retornam um novo objeto.

Como Duration.ofDays(1) difere de Period.ofDays(1)?

Duration.ofDays(1) é sempre 24 horas (86400 segundos). Period.ofDays(1) é 1 dia de calendário, que durante o DST pode ser 23 ou 25 horas. Para cálculos de tempo precisos, use Duration; para cálculos de calendário, use Period.

Como converter Duration para milissegundos?

Use o método toMillis(). Ele retorna um long — o número de milissegundos na Duration. Para nanossegundos, use toNanos(). Atenção: toNanos() pode estourar long em valores > 292 anos. Para Durations grandes, use toSeconds() ou toMinutes().

Como calcular Duration entre dois LocalTime?

Use Duration.between(startTime, endTime). Se endTime for menor que startTime (turno noturno), Duration será negativa. Adicione 24 horas: duration.plusHours(24), se endTime for considerado o dia seguinte.

Resumo

  • Duration — uma classe imutável para duração baseada em tempo com precisão de nanossegundos, ideal para medir intervalos.
  • A principal diferença de Period — Duration mede segundos (tempo físico), Period mede unidades de calendário.
  • Criada através de Duration.between() para a diferença entre momentos ou através de fábricas estáticas ofMinutes, ofHours, ofDays.
  • Suporta aritmética: plus, minus, multipliedBy, dividedBy, bem como comparação através de Comparable e abs.
  • No Android, Duration é usada para calcular timeouts, intervalos de sincronização, temporizadores e medição de desempenho.
  • Ao exibir ao usuário, formate Duration manualmente — toString() retorna ISO-8601, que não é legível para humanos.
  • Lembre-se de que Duration pode ser negativa — verifique isNegative() e use abs() para cálculos corretos.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também