วันที่และช่วงเวลา (Dates & Periods)
การคำนวณวันที่ในระบบการเงินต้องการความแม่นยำสูงสุด การตรวจสอบปีอธิกสุรทิน (Leap Year) และการคำนวณปฏิทินโดยไม่มีค่าใช้จ่ายแฝงของ Runtime ภายนอก SabiQuant มอบชนิดข้อมูล Date และ Period ในตัวที่พัฒนาขึ้นบน std โดยเฉพาะ
ชนิดข้อมูล Date
โครงสร้าง Date แทนวันที่ในปฏิทินเกรกอเรียน (Gregorian Calendar) พร้อมกฎการตรวจสอบความถูกต้อง:
use sabiquant::core::{Date, Month, Weekday};
fn main() -> Result<(), Box<dyn std::error::Error>> { // สร้างวันที่จาก ปี, เดือน, วัน let d1 = Date::from_ymd(2025, 2, 28)?;
// ตรวจสอบปีอธิกสุรทิน (Leap Year) println!("Is 2024 a leap year? {}", Date::is_leap_year(2024)); // true println!("Is 2025 a leap year? {}", Date::is_leap_year(2025)); // false
// การเพิ่ม/ลดวัน let tomorrow = d1.add_days(1); println!("Next day: {}", tomorrow); // 2025-03-01
// ตรวจหาวันในสัปดาห์ (Day of the week) let weekday: Weekday = d1.weekday(); println!("Weekday: {:?}", weekday);
// คำนวณจำนวนวันระหว่างสองช่วง let d2 = Date::from_ymd(2025, 12, 31)?; let days_diff = d2.days_between(&d1); println!("Days between: {}", days_diff);
Ok(())}ช่วงเวลาสัญญาการเงินและชนิดข้อมูล Period (Tenors)
Tenor กำหนดช่วงระยะเวลาที่ใช้กันทั่วไปในสัญญาทางการเงิน (เช่น 3M, 6M, 1Y, 5Y):
use sabiquant::core::{Date, Period, TimeUnit};
fn main() -> Result<(), Box<dyn std::error::Error>> { let start = Date::from_ymd(2025, 1, 31)?;
// สร้าง Period ตามหน่วยเวลาต่างๆ let p_3m = Period::new(3, TimeUnit::Months); let p_1y = Period::years(1); let p_2w = Period::weeks(2); let p_10d = Period::days(10);
// อนุสัญญาการเลื่อนวันสิ้นเดือน (End of Month - EOM roll) let end_3m = start.advance_period(&p_3m, true); println!("31 Jan + 3M (with EOM): {}", end_3m); // 2025-04-30
Ok(())}คุณลักษณะด้านประสิทธิภาพ (Performance Characteristics)
- Zero Allocations:
Dateเป็นCopytype ที่ถูกจัดเก็บภายในรูปแบบจำนวนเต็มขนาด 32-bit (Packed integer) - Constant Time: การบวกวัน, การค้นหาวันในสัปดาห์, และการตรวจสอบปีอธิกสุรทิน ทำงานที่ความเร็ว โดยไม่มี Branch misprediction บนฮาร์ดแวร์สมัยใหม่