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 สะดวกสำหรับการคำนวณเวลาอั้ง Teaม์อาวท์ ช่วงการซิงค์ และระยะเวลาการทำงาน

Duration คืออะไร?

Duration คือคลาสที่จำลองปริมาณเวลาเป็นวินาทีและนาโนวินาที มันแสดงระยะเวลาที่อิงเวลา ซึ่งเป็นจำนวนวินาทีทางกายภาพที่ไม่อิงกับปฏิทิน Duration สามารถคิดได้ว่าเป็น “125 นาที” หรือ “2 ชั่วโมง 5 นาที” — ต่างจาก Period ที่จะพูดว่า “2 เดือน”

การแสดงภายในของ Duration ประกอบด้วยสองฟิลด์: long seconds (วินาที) และ int nanos (นาโนวินาที 0 ถึง 999999999) ค่าสามารถเป็นลบได้ — หมายถึงระยะเวลาย้อนหลังในเวลา ค่าสูงสุดคือ ±31557014167219200 วินาที

ตาม Baeldung (2024) Duration เป็นคลาสหลักสำหรับการคำนวณระยะเวลาการทำงาน การตั้งค่าเวลาอั้ง และการวัดประสิทธิภาพ Duration ไม่สามารถเปลี่ยนแปลงได้และมันปลอดภัยต่อเสน้นเรียกชันด์ ทำให้สามารถใช้งานในสภาพแวดล้อมหลายเสน้นเรียกชันด์โดยไม่ต้องมีการซิงค์

คลาสนี้ใช้งานอินเทอร์เฟส Comparable, TemporalAmount และ TemporalUnit TemporalAmount ช่วยให้สามารถใช้ Duration ในเมธอด plus/minus ของคลาส LocalTime, LocalDateTime, Instant และ ZonedDateTime

Duration vs Period: ต่างกันอย่างไร?

ข้อแตกต่างหลักคือ Duration วัดจำนวนวินาทีที่แม่นยำ (อิงเวลา) ในขณะที่ Period วัดหน่วยปฏิทิน (อิงวันที่): ปี เดือน วัน Duration บอกว่า “ผ่านไป 86400 วินาที” Period บอกว่า “ผ่านไป 1 วัน” ความแตกต่างจะเห็นได้ชัดเจนในระยะการเปลี่ยนเวลาออมแสง — 1 วันใน Period เป็น 1 วันปฏิทินเสมอ แต่ 86400 วินาทีใน Duration อาจสอดคล้องกับ 23 หรือ 25 ชั่วโมงในระยะ DST

Duration ใช้สำหรับการวัดเวลาทางกายภาพ: เวลาอั้งการเชื่อมต่อ เวลาดำเนินการคำสั่ง ช่วงระหว่างสอง Instant Period ใช้สำหรับการคำนวณปฏิทิน: อายุของบุคคล (Period.between(dateOfBirth, today)) ระยะเวลาสัญญา

Duration ทำงานกับวินาทีและนาโนวินาที ดังนั้นจึงสามารถแบ่งเป็นส่วนย่อย (ชั่วโมง นาที) ได้ Period ทำงานกัปปี เดือน และวัน — หน่วยปฏิทินที่ไม่สามารถแบ่งได้ ตาม Oracle Java Tutorial (2024) การเลือกระหว่าง Duration และ Period ขึ้นอยู่กับประเภทของงาน: เวลาที่แม่นยำเปรียบเทียบวันที่ปฏิทิน

การสร้าง 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 ที่ไม่ถูกต้องสำหรับส่วนติดต่อผู้ใช้ 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 ใช้สำหรับคำนวณเวลาอั้ง ช่วงการซิงค์ ตัวจับเวลา และการวัดประสิทธิภาพ
  • เมื่อแสดงผลต่อผู้ใช้ จงจัดรูปแบบ Duration ด้วยตนเอง — toString() ส่งออก ISO-8601 ซึ่งมนุษย์อ่านไม่รู้เรื่อง
  • โปรดจำไว้ว่า Duration สามารถเป็นลบได้ — ตรวจสอบ isNegative() และใช้ abs() สำหรับการคำนวณที่ถูกต้อง

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม