Duration — τι είναι, υπολογισμός διάρκειας στο Android

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-07-13 Χρόνος ανάγνωσης: 9 λεπ

Duration — μια αμετάβλητη κλάση από το πακέτο java.time, που αντιπροσωπεί τη διάρκεια μεταξύ δύο χρονικών στιγμών σε δευτερόλεπτα και νανοδευτερόλεπτα. Το Duration μετρά ποσότητα χρόνου βασισμένη στον χρόνο — ώρες, λεπτά, δευτερόλεπτα, χιλιοστά δευτερολέπτου και νανοδευτερόλεπτα. Σύμφωνα με την προδιαγραφή Oracle Java 17 (2024), σε αντίθεση με το Period (που μετρά έτη-μήνες-ημέρες), το Duration εργάζεται με ακριβείς μονάδες χρόνου και δεν εξαρτάται από το ημερολόγιο.

Κύρια σημεία

  • Duration — αμετάβλητη κλάση για μέτρηση διάρκειας σε δευτερόλεπτα και νανοδευτερόλεπτα.
  • Σε αντίθεση με το Period, το Duration εργάζεται με μονάδες βασισμένες στον χρόνο (ώρες, λεπτά, δευτερόλεπτα), όχι βασισμένες σε ημερομηνία (ημέρες, μήνες, έτη).
  • Δημιουργείται μέσω Duration.between(start, end), Duration.ofMinutes(), Duration.ofHours() και άλλων στατικών εργοστασίων.
  • Υποστηρίζει αριθμητικές πράξεις: plus(), minus(), multipliedBy(), dividedBy(), negated().
  • Για την ανάπτυξη Android, το Duration είναι βολικό για υπολογισμό timeouts, διαστημάτων συγχρονισμού και διάρκειας λειτουργιών.

Τι είναι το Duration;

Duration — είναι μια κλάση που μοντελάρει την ποσότητα χρόνου σε δευτερόλεπτα και νανοδευτερόλεπτα. Αντιπροσωπεί μια διάρκεια βασισμένη στον χρόνο, δηλαδή τον φυσικό αριθμό δευτερολέπτων, χωρίς σύνδεση με ημερολόγιο. Το Duration μπορεί να αναπαρασταθεί ως “125 λεπτά” ή “2 ώρες 5 λεπτά” — σε αντίθεση με το Period, που θα πει “2 μήνες”.

Η εσωτερική αναπαράσταση του Duration αποτελείται από δύο πεδία: long seconds (δευτερόλεπτα) και int nanos (νανοδευτερόλεπτα, από 0 έως 999999999). Η τιμή μπορεί να είναι αρνητική — αυτό σημαίνει διάρκεια προς τα πίσω στον χρόνο. Η μέγιστη τιμή είναι ±31557014167219200 δευτερόλεπτα.

Σύμφωνα με το Baeldung (2024), το Duration είναι η κλειδιά κλάση για υπολογισμό διάρκειας λειτουργιών, ρύθμιση timeouts και μέτρηση απόδοσης. Το Duration είναι αμετάβλητο και thread-safe, κάτι που επιτρέπει τη χρήση του σε πολυνεματικό περιβάλλον χωρίς συγχρονισμό.

Η κλάση υλοποιεί τις διεπαφές Comparable, TemporalAmount και TemporalUnit. Το TemporalAmount επιτρέπει τη χρήση του Duration σε μεθόδους plus/minus των κλάσεων LocalTime, LocalDateTime, Instant και ZonedDateTime.

Duration vs Period: ποια είναι η διαφορά;

Η κύρια διαφορά — το Duration μετρά τον ακριβή αριθμό δευτερολέπτων (time-based), ενώ το Period μετρά ημερολογιακές μονάδες (date-based): έτη, μήνες, ημέρες. Το Duration λέει: “περάσαν 86400 δευτερόλεπτα”. Το Period λέει: “περάσε 1 ημέρα”. Η διαφορά εκδηλώνεται κατά τη μετάβαση σε θερινή ώρα — 1 ημέρα στο Period είναι πάντα ίση με 1 ημέρα στο ημερολόγιο, ενώ 86400 δευτερόλεπτα στο Duration μπορούν να αντιστοιχούν σε 23 ή 25 ώρες κατά τη DST.

Το Duration χρησιμοποιείται για μέτρηση φυσικού χρόνου: timeouts σύνδεσης, χρόνος εκτέλεσης αιτήματος, διάστημα μεταξύ δύο Instant. Το Period χρησιμοποιείται για ημερολογιακούς υπολογισμούς: ηλικία ενός ατόμου (Period.between(ημερομηνίαΓέννησης, σήμερα)), περίοδος ισχύος συμβολαίου.

Το Duration εργάζεται με δευτερόλεπτα και νανοδευτερόλεπτα, επομένως μπορεί να διαιρεθεί σε μέρη (ώρες, λεπτά). Το Period εργάζεται με έτη, μήνες και ημέρες — αδιαίρετες ημερολογιακές μονάδες. Σύμφωνα με το Oracle Java Tutorial (2024), η επιλογή μεταξύ Duration και Period εξαρτάται από τον τύπο της εργασίας: ακριβής χρόνος vs ημερολογιακές ημερομηνίες.

Δημιουργία Duration

Ο πιο συνηθισμένος τρόπος — Duration.between(Temporal start, Temporal end). Το Temporal μπορεί να είναι Instant, LocalTime, LocalDateTime, ZonedDateTime — οποιοδήποτε τύπος που υλοποιεί το Temporal. Η μέθοδος επιστρέφει ένα Duration που αντιπροσωπεί τη διαφορά start - end (μπορεί να είναι αρνητική).

Στατικές εργοστασιακές μέθοδοι: Duration.ofSeconds(long), ofMinutes(long), ofHours(long), ofDays(long), ofMillis(long), ofNanos(long). Υπάρχει επίσης η of(long amount, TemporalUnit unit) για αυθαίρετες μονάδες — ChronoUnit.HOURS, ChronoUnit.MINUTES και άλλες.

Η μέθοδος parse(CharSequence) δέχεται ένα συμβολοσειρά σε μορφή ISO-8601: “PT1H30M” (1 ώρα 30 λεπτά), “PT45S” (45 δευτερόλεπτα), “P2DT3H” (2 ημέρες 3 ώρες). Το συμβολοσειρά ξεκινά πάντα με “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")

Αριθμητική με Duration

Το Duration υποστηρίζει ένα πλήρες σύνολο αριθμητικών πράξεων. Οι μεθοδοι plus(Duration) και minus(Duration) προσθέτουν ή αφαιρούν μία άλλη διάρκεια. Οι μεθοδοι plusDays(), plusHours(), plusMinutes(), plusSeconds(), plusMillis(), plusNanos() — για ακριβή προσθήκη μονάδων.

Για πολλαπλασιασμό και διαίρεση χρησιμοποιούνται οι multipliedBy(long) και dividedBy(long). Το Duration.multipliedBy(2) διπλασιάζει τη διάρκεια. Το Duration.dividedBy(3) διαιρεί σε τρία μέρη με στρογγυλοποίηση προς τα κάτω. Η μέθοδος negated() αντιστρέφει το πρόσημο — η θετική γίνεται αρνητική και αντιστρόφως.

Η μέθοδος abs() επιστρέφει ένα Duration με την απόλυτη (θετική) τιμή. Το isNegative() και isZero() — έλεγχοι. Το toDays(), toHours(), toMinutes(), toSeconds(), toMillis(), toNanos() — μετατροπή σε αντίστοιχες μονάδες.

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()

Σύγκριση Duration

Το Duration υλοποιεί τη διεπαφή Comparable, κάτι που επιτρέπει τη φυσική σύγκριση διαρκειών. Η μέθοδος compareTo() επιστρέφει αρνητικό αριθμό, μηδέν ή θετικό αριθμό. Οι μεθοδοι isNegative() και isZero() — γρήγοροι έλεγχοι. Για ρητή σύγκριση χρησιμοποιήστε equals() — δύο Duration είναι ίσα αν έχουν τα ίδια δευτερόλεπτα και νανοδευτερόλεπτα.

Καθώς το Duration μπορεί να είναι αρνητικό, η σύγκριση “μεγαλύτερο” ή “μικρότερο” λειτουργεί λαμβάνοντας υπόψη το πρόσημο. -5 λεπτά είναι μικρότερα από 2 λεπτά. Η μέθοδος abs() είναι χρήσιμη αν χρειάζεται να συγκρίνετε “απόλυτα” μήκη ανεζάρτητα από τη κατεύθυνση.

Στο Kotlin, το Duration υποστηρίζει τελεστές σύγκρισης μέσω υπερφόρτωσης τελεστών: a < b, a > b, a <= b. Επίσης τα plus και minus είναι διαθέσιμα ως τελεστές: a + b, a - b.

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

if (short < long) {
    Log.d("Duration", "5 λεπτά είναι λιγότερο από 10")
}

val negative = Duration.ofMinutes(-3)
Log.d("Duration", "Αρνητικό: ${negative.isNegative()}")

Duration σε πραγματικές εργασίες Android

Το πρώτο παράδειγμα — ρύθμιση περιοδικού συγχρονισμού με τον διακομιστή. Το Duration χρησιμοποιείται για τον υπολογισμό του διαστήματος μεταξύ συγχρονισμών και τον έλεγχο αν το χρονικό όριο χωρίς ενημέρωση έχει υπερβαθεί.

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)
}

Το δεύτερο παράδειγμα — μέτρηση χρόνου εκτέλεσης λειτουργίας για καταγραφή απόδοσης.

kotlin
fun measureExecution(
    tag: String,
    block: () -> Unit
) {
    val start = Instant.now()
    block()
    val duration = Duration.between(start, Instant.now())
    Log.d(tag, "Εκτελέστηκε σε ${duration.toMillis()} ms")
}

Το τρίτο παράδειγμα — υπολογισμός υπόλοιπου χρόνου χρονομετρητή (π.χ. αντίστροφη μέτρηση μέχρι το τέλος μιας προσφοράς).

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
}

Μετατροπή Duration σε συμβολοσειρά

Η μέθοδος toString() επιστρέφει το Duration σε μορφή ISO-8601: “PT1H30M” (1 ώρα 30 λεπτά), “PT45.5S” (45.5 δευτερόλεπτα). Αυτή η μορφή είναι βολική για ανταλλαγή μεταξύ μηχανών, αλλά όχι για εμφάνιση στον χρήστη.

Για μορφή αναγνώσιμη από ανθρώπους, χρησιμοποιήστε toDays(), toHours(), toMinutes(), toSeconds() με μεμονωμένη σύνθεση του συμβολοσειράς. Παράδειγμα: “${days} η ${hours} ώ ${minutes} λ”. Σημειώστε ότι το toHours() επιστρέφει το συνολικό αριθμό ωρών, όχι τις ώρες μέσα σε μια ημέρα.

Για διαίρεση του Duration σε συνιστώσες χρησιμοποιείται ο τύπος: val hours = duration.toHours(); val minutes = duration.toMinutes() % 60; val seconds = duration.seconds % 60. Σύμφωνα με το Apache Commons Lang (2024), η βιβλιοθήκη DurationFormatUtils παρέχει επιπλέον δυνατότητες μορφοποίησης.

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")
    }
}

Τυπικά λάθη

Πρώτο λάθος — σύγχυση μεταξύ Duration και Period κατά την εργασία με ημερομηνίες. Το Duration μετρά δευτερόλεπτα, επομένως το Duration.ofDays(1) είναι πάντα 24 ώρες (86400 δευτερόλεπτα), ανεξάρτητα από τη μετάβαση σε θερινή ώρα. Αν χρειάζεστε ημερολογιακή ημέρα, χρησιμοποιήστε Period.ofDays(1).

Δεύτερο λάθος — απώλεια νανοδευτερολέπτων κατά τη μετατροπή. Το Duration μπορεί να αποθηκεύει νανοδευτερόλεπτα, αλλά το toMillis() και toSeconds() τα απορρίπτουν. Για ακριβείς υπολογισμούς χρησιμοποιήστε toNanos() ή εργαστείτε απευθείας με Duration, χωρίς μετατροπή σε πρωτογενείς τύπους.

Τρίτο λάθος — αγνόηση αρνητικών Duration. Το Duration.between(start, end) επιστρέφει start - end. Αν το start είναι μετά το end, το Duration θα είναι αρνητικό. Η μέθοδος abs() βοηθά να λάβετε την απόλυτη τιμή, και το isNegative() να ελέγξετε τη σειρά των ορισμάτων.

Τέταρτο λάθος — λανθασμένη μορφοποίηση του Duration για UI. Το Duration.toString() επιστρέφει ISO-8601, το οποίο είναι δυσανάγνωστο. Πάντα μορφοποιείτε το Duration χειροκίνητα για εμφάνιση στον χρήστη, χρησιμοποιώντας toHours(), toMinutes() και toSeconds() με το σωστό υπόλοιπο της διαίρεσης.

Συχνές Ερωτήσεις

Μπορεί το Duration να είναι αρνητικό;

Ναι, το Duration μπορεί να είναι αρνητικό. Το Duration.between(start, end) επιστρέφει start - end. Αν το start είναι μετά το end, το Duration θα είναι αρνητικό. Χρησιμοποιήστε abs() για να λάβετε την απόλυτη τιμή ή isNegative() για έλεγχο.

Πώς να προσθέσω δύο Duration;

Χρησιμοποιήστε τη μέθοδο plus(Duration) ή τον τελεστή + στο Kotlin: duration1 + duration2. Το αποτέλεσμα — ένα νέο Duration. Η μέθοδος minus(Duration) αφαιρεί μια διάρκεια από την άλλη. Όλες οι λειτουργίες είναι αμετάβλητες και επιστρέφουν νέο αντικείμενο.

Σε τι διαφέρει το Duration.ofDays(1) από το Period.ofDays(1);

Το Duration.ofDays(1) είναι πάντα 24 ώρες (86400 δευτερόλεπτα). Το Period.ofDays(1) είναι 1 ημερολογιακή ημέρα που κατά τη DST μπορεί να είναι 23 ή 25 ώρες. Για υπολογισμούς με ακριβή ώρα χρησιμοποιήστε Duration, για ημερολογιακούς — Period.

Πώς να μετατρέψω το Duration σε χιλιοστά δευτερολέπτου;

Χρησιμοποιήστε τη μέθοδο toMillis(). Επιστρέφει long — τον αριθμό χιλιοστών δευτερολέπτων στο Duration. Για νανοδευτερόλεπτα χρησιμοποιήστε toNanos(). Προσοχή: το toNanos() μπορεί να υπερχειλίσει το long σε τιμές > 292 έτη. Για μεγάλα Duration χρησιμοποιήστε toSeconds() ή toMinutes().

Πώς να υπολογίσω το Duration μεταξύ δύο LocalTime;

Χρησιμοποιήστε Duration.between(startTime, endTime). Αν το endTime είναι μικρότερο από το startTime (νυχτερινή βάρδια), το Duration θα είναι αρνητικό. Προσθέστε 24 ώρες: duration.plusHours(24), αν υποθέτετε ότι το endTime είναι η επόμενη ημέρα.

Περίληψη

  • Duration — αμετάβλητη κλάση για διάρκεια βασισμένη στον χρόνο με ακρίβεια νανοδευτερολέπτου, ιδανική για μέτρηση διαστημάτων.
  • Η κύρια διαφορά από το Period — το Duration μετρά δευτερόλεπτα (φυσικό χρόνο), το Period — ημερολογιακές μονάδες.
  • Δημιουργείται μέσω Duration.between() για διαφορά μεταξύ στιγμών ή μέσω στατικών εργοστασιών ofMinutes, ofHours, ofDays.
  • Υποστηρίζει αριθμητική: plus, minus, multipliedBy, dividedBy, καθώς και σύγκριση μέσω Comparable και abs.
  • Στο Android, το Duration χρησιμοποιείται για υπολογισμό timeouts, διαστημάτων συγχρονισμού, χρονομετρητών και μέτρησης απόδοσης.
  • Κατά την εμφάνιση στον χρήστη, μορφοποιήστε το Duration χειροκίνητα — το toString() επιστρέφει ISO-8601, μη αναγνώσιμο από ανθρώπους.
  • Λάβτε υπόψη ότι το Duration μπορεί να είναι αρνητικό — ελέγξτε το isNegative() και χρησιμοποιήστε abs() για σωστούς υπολογισμούς.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης