Java Duration.truncatedTo: ปัดช่วงเวลาเป็น bucket โดยไม่ใช้เลขหารเอง
งาน 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