Duration — คลาสสถานะที่ไม่สามารถเปลี่ยนแปลงได้จากแพ็คเกจ java.time ซึ่งแสดงระยะเวลาระหว่างสองช่วงเวลาเป็นวินาทีและนาโนวินาที Duration วัดปริมาณเวลาที่องตามเวลา — ชั่วโมง นาที วินาที มิลลิวินาที และนาโนวินาที ตามข้อกำหนดจาก Oracle Java 17 (2024) ต่างจาก Period (ซึ่งวัดปี-เดือน-วัน) 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 วัดจำนวนวินาทีที่แม่นยำ (อิงเวลา) ในขณะที่ 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.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) เสมอ
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 รองรับชุดการดำเนินการเลขคนิตที่สมบูรณ์ เมธอด 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() แปลงเป็นหน่วยที่สอดคล้องกัน
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 ใช้งานอินเทอร์เฟส Comparable ทำให้สามารถเปรียบเทียบระยะเวลาได้อย่างเป็นธรรมชาติ เมธอด compareTo() ส่งคืนตัวเลขลบ ศูนย์ หรือบวก isNegative() และ isZero() เป็นการตรวจสอบอย่างรวดเร็ว สำหรับการเปรียบเทียบอย่างชัดเจน ใช้ equals() — Duration สองอันเท่ากันหากวินาทีและนาโนวินาทีตรงกัน
เนื่องจาก Duration สามารถเป็นลบได้ การเปรียบเทียบ “มากกว่า” หรือ “น้อยกว่า” ทำงานโดยคำนึงถึงเครื่องหมาย -5 นาทีน้อยกว่า 2 นาที เมธอด abs() มีประโยชน์สำหรับการเปรียบเทียบความยาว “สมบูรณ์” โดยไม่คำนึงถึงทิศทาง
ใน Kotlin Duration รองรับตัวดำเนินการเปรียบเทียผ่านการโอเวอร์โหลดตัวดำเนินการ: a < b, a > b, a <= b นอกจากนี้ plus และ minus ยังสามารถใช้เป็นตัวดำเนินการได้: a + b, a - b
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 ใช้ในการคำนวณช่วงระหว่างการซิงค์และตรวจสอบว่าเกินอั้งเวลาที่ไม่มีการอัปเดตหรือไม่
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)
}
ตัวอย่างที่สองคือการวัดเวลาดำเนินการสำหรับการบันทึกประสิทธิภาพ
fun measureExecution(
tag: String,
block: () -> Unit
) {
val start = Instant.now()
block()
val duration = Duration.between(start, Instant.now())
Log.d(tag, "ดำเนินการใน ${duration.toMillis()} ms")
}
ตัวอย่างที่สามคือการคำนวณเวลาที่เหลือของตัวจับเวลา (ตัวอย่าง: การนับถอยหลังจนกระทั่งสิ้นโปรโมชัน)
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
}
เมธอด 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 ให้ความสามารถในการจัดรูปแบบเพิ่มเติม
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.between(start, end) ส่งคืน start - end หาก start อยู่หลัง end Duration จะเป็นลบ ใช้ abs() เพื่อรับค่าสมบูรณ์หรือ isNegative() เพื่อตรวจสอบ
ใช้เมธอด plus(Duration) หรือตัวดำเนินการ + ใน Kotlin: duration1 + duration2 ผลลัพธ์เป็น Duration ใหม่ เมธอด minus(Duration) ลบระยะเวลาหนึ่งจากอีกอัน การดำเนินการทั้งหมดไม่สามารถเปลี่ยนแปลงได้และส่งคืนวัตถุใหม่
Duration.ofDays(1) เป็น 24 ชั่วโมง (86400 วินาที) เสมอ Period.ofDays(1) เป็น 1 วันปฏิทิน ซึ่งในระยะ DST อาจเป็น 23 หรือ 25 ชั่วโมง สำหรับการคำนวณเวลาที่แม่นยำ ใช้ Duration สำหรับการคำนวณปฏิทิน ใช้ Period
ใช้เมธอด toMillis() โดยจะส่งคืน long — จำนวนมิลลิวินาทีใน Duration สำหรับนาโนวินาที ใช้ toNanos() ข้อควรระวัง: toNanos() อาจลัน long ได้ที่ค่า > 292 ปี สำหรับ Duration ขนาดใหญ่ ใช้ toSeconds() หรือ toMinutes()
ใช้ Duration.between(startTime, endTime) หาก endTime น้อยกว่า startTime (กะบรรกกลางคืน) Duration จะเป็นลบ เพิ่ม 24 ชั่วโมง: duration.plusHours(24) หากถือว่า endTime เป็นวันถัดไป
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม