นากกายต้นฉบับกำลังจัดแท่งช่วงเวลาลงช่อง bucket นาทีบนโต๊ะทำงานสว่าง

Java Duration.truncatedTo: ปัดช่วงเวลาเป็น bucket โดยไม่ใช้เลขหารเอง

พี่โชว์Engineering

งาน metrics และ cache key มักต้องตัดเศษช่วงเวลาให้เหลือหน่วยเต็ม Duration.truncatedTo สื่อ intent ชัดกว่าหารวินาทีเอง และรักษา nanosecond semantics ของ Duration ครับ

import java.time.Duration;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        Duration latency = Duration.ofSeconds(125).plusMillis(900);
        assert latency.truncatedTo(ChronoUnit.MINUTES).equals(Duration.ofMinutes(2));
        assert latency.truncatedTo(ChronoUnit.SECONDS).equals(Duration.ofSeconds(125));

        Duration negative = Duration.ofSeconds(-125).minusMillis(900);
        assert negative.truncatedTo(ChronoUnit.MINUTES).equals(Duration.ofMinutes(-2));
        assert Duration.ZERO.truncatedTo(ChronoUnit.SECONDS).isZero();
    }
}

Truncate ไม่ใช่ round

การ truncate ตัดส่วนย่อยเข้าหาศูนย์ จึงต่างจากการปัดค่าที่อาจขึ้น bucket ถัดไป หน่วยต้องมีระยะคงที่และหารหนึ่งวันลงตัวตาม contract; เดือนกับปีมีความยาวไม่คงที่ จึงควรใช้ Period หรือ date-time boundary แทน

ถ้าต้อง group event ตามนาฬิกาจริงและ timezone ให้ truncate Instant/ZonedDateTime ตามกติกางาน ไม่เอา elapsed Duration ไปแทน timestamp เหมือนแยก “ใช้เวลาเดินทางกี่นาที” ออกจาก “รถออกกี่โมง”

Recap

  • ใช้เมื่ออยากตัดเศษ ไม่ใช่ปัดใกล้สุด
  • ทดสอบค่าติดลบ
  • ใช้เฉพาะหน่วยคงที่ที่ API รองรับ
  • แยก elapsed duration ออกจาก wall-clock bucket