1 คะแนน โดย GN⁺ 2025-04-14 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Whenever เป็นไลบรารีที่พัฒนาต่อยอดจาก datetime ของ Python เพื่อให้มี ความปลอดภัยด้าน DST และ ความปลอดภัยด้านชนิดข้อมูล
  • ใช้งานได้ทั้งด้วย Rust และ Python ล้วน พร้อม ประสิทธิภาพ ที่ยอดเยี่ยม
  • เหนือกว่าไลบรารีมาตรฐานของ Python รวมถึง Arrow และ Pendulum ในด้าน การจัดการ DST และ ความปลอดภัยด้านชนิดข้อมูล
  • รองรับ ความละเอียดระดับนาโนวินาที และ การปรับปรุง GIL ล่าสุด พร้อมเพิ่มประสิทธิภาพผ่าน ส่วนขยาย Rust
  • เผยแพร่ภายใต้ MIT License และยังคงพัฒนาอย่างต่อเนื่องผ่าน ข้อเสนอแนะ

แนะนำ Whenever

  • Whenever เป็นไลบรารีที่สร้างขึ้นเพื่อแก้ข้อจำกัดของโมดูล datetime ใน Python
  • มอบทั้ง ความปลอดภัยด้าน DST และ ความปลอดภัยด้านชนิดข้อมูล เพื่อเพิ่มความถูกต้องของโค้ด
  • พัฒนาด้วย Rust และ Python ล้วน และมีประสิทธิภาพสูง

ข้อจำกัดของไลบรารีมาตรฐาน

  • datetime ของ Python ไม่ได้คำนึงถึง DST เสมอไป
  • ใน ระบบชนิดข้อมูล ไม่สามารถแยก datetime แบบ naive และ aware ได้

เปรียบเทียบกับไลบรารีอื่น

  • Arrow มี API ที่ใช้งานง่าย แต่ยังไม่สามารถแก้ปัญหาหลักได้
  • Pendulum แก้ปัญหา DST ได้บางส่วน แต่มีประสิทธิภาพลดลงและขาดการดูแลรักษาอย่างต่อเนื่อง

จุดเด่นของ Whenever

  • มีทั้ง การคำนวณเชิงเวลาแบบปลอดภัยต่อ DST และ API ที่ปลอดภัยด้านชนิดข้อมูล
  • ประสิทธิภาพ สูง และดีขึ้นอีกผ่าน ส่วนขยาย Rust
  • รองรับ ความละเอียดระดับนาโนวินาที และ การปรับปรุง GIL ล่าสุด

เริ่มต้นใช้งานอย่างรวดเร็ว

  • มีชนิดข้อมูลแบบระบุชัดเจน เช่น Instant, ZonedDateTime, LocalDateTime
  • รองรับ การคำนวณเชิงเวลาแบบปลอดภัยต่อ DST และ การแปลงค่าแบบชัดเจน
  • รองรับการฟอร์แมตและพาร์สในรูปแบบ ISO8601, RFC3339, RFC2822

โรดแมป

  • เวอร์ชัน 0.x: ทำให้ฟีเจอร์ครบถ้วนเทียบเท่าและปรับปรุง API
  • เวอร์ชัน 1.0: ทำให้ API มีเสถียรภาพและรองรับความเข้ากันได้ย้อนหลัง

ข้อจำกัด

  • รองรับปฏิทินเกรกอเรียนตั้งแต่ ค.ศ. 1 ถึง 9999
  • รองรับ ออฟเซ็ตเขตเวลา ที่สอดคล้องกับ IANA TZ DB
  • ไม่รองรับ วินาทีอธิกสุรทิน

นโยบายการจัดการเวอร์ชันและความเข้ากันได้

  • Whenever ใช้ Semantic Versioning
  • ก่อนถึงเวอร์ชัน 1.0 API อาจมีการเปลี่ยนแปลงได้

ใบอนุญาต

  • เผยแพร่ภายใต้ MIT License และ dependency ฝั่ง Rust ใช้ใบอนุญาตแบบอนุญาตที่คล้ายกัน

คำขอบคุณ

  • ได้รับแรงบันดาลใจจากโปรเจ็กต์ Temporal, Noda Time, Joda Time
  • อ้างอิงกราฟเปรียบเทียบ benchmark จากโปรเจ็กต์ Ruff

1 ความคิดเห็น

 
GN⁺ 2025-04-14
ความคิดเห็นจาก Hacker News
  • ถ้ายังไม่ได้อ่านบล็อกโพสต์ที่อธิบายว่าทำไมไลบรารีนี้ถึงมีอยู่ ขอแนะนำให้อ่าน ชื่อคือ "Ten Python datetime pitfalls, and what libraries are (not) doing about it"
  • ไลบรารีนี้แก้ปัญหาการละเมิด Liskov ในไลบรารีมาตรฐาน ในไลบรารีมาตรฐานสามารถเปรียบเทียบวันที่กันได้ แต่ถ้าเปรียบเทียบ datetime กับวันที่จะเกิดข้อผิดพลาด ไม่นานมานี้ฉันเจอปัญหานี้จนลำบากในที่ทำงาน
  • เคยใช้ Arrow, Delorean, Pendulum และ datetime ของไลบรารีมาตรฐานมาแล้ว แต่สุดท้ายเลือก Whenever เพราะดูเหมาะกับการจัดการ datetime จริงมากกว่า และเหมือนจะมีการดูแลรักษาอย่างต่อเนื่องมากกว่า รู้สึกว่าไลบรารีอื่นมักพลาดเคสขอบอยู่เสมอ ส่วน Pendulum ดูเหมือนจะฝังลึกอยู่ใน API มากกว่า
  • มีฉันคนเดียวหรือเปล่าที่ใช้ไลบรารีมาตรฐาน อ่านเอกสารกับบันทึกการเปลี่ยนแปลงอย่างละเอียด แล้วลงมือทำฟีเจอร์ที่ต้องการเอง? ฉันเรียนรู้อย่างยากลำบากแล้วว่า dependency ทำโปรเจกต์พังได้ ไม่ได้แปลว่าไลบรารีนี้ไม่ดี แน่นอนว่ามันมีกรณีใช้งานของมัน
  • มีให้ทั้ง Rust และ Python ล้วน ๆ ความซับซ้อนจากการต้องใช้แพ็กเกจไบนารีหรือคอมไพล์เองไม่คุ้มกับข้อได้เปรียบด้านประสิทธิภาพ ส่วนเวอร์ชัน Python ล้วนต้องบิลด์จากซอร์สและส่งแฟล็กพิเศษ จึงระบุไว้ใน requirements.txt ไม่ได้
  • ถ้าประสิทธิภาพไม่ใช่สิ่งสำคัญสูงสุด ก็ใช้เวอร์ชัน Python ล้วนได้เหมือนกัน อยากเห็นเบนช์มาร์กของ implementation แบบ Python ล้วนด้วย ถ้ามันช้ากว่า Arrow ล่ะ?
  • น่าสนใจที่ Pandas ไม่เพิ่มการเปรียบเทียบ datetime เข้าไป น่าจะเป็นไลบรารีที่ถูกใช้จัดการวันที่มากกว่าไลบรารีอื่นเสียอีก
  • มีใครรู้ไหมว่าเมื่อไรปัญหาเรื่องประสิทธิภาพถึงจะสำคัญ? ฉันเข้าใจว่า datetime เป็นอ็อบเจ็กต์อายุสั้น คงไม่อยากมีอ็อบเจ็กต์ datetime หลายพันตัวอยู่ในโค้ดเบส เกือบทุกกรณี UTC ก็เพียงพอแล้ว เวลาอยากกรอง/จัดบักเก็ต/สรุปผลตามช่วง ก็ใช้ datetime ที่มี tz เพื่อกำหนดเกณฑ์การกรอง/จัดบักเก็ต/สรุปผล แล้วแปลงเป็น UTC เพื่อกลับไปเทียบแบบ int ต่อ กรณีส่วนใหญ่ที่ Whenever จัดการน่าจะเป็นตอนที่ datetime เป็นอ็อบเจ็กต์ระยะยาว ซึ่งฉันไม่เคยรู้สึกว่าต้องการแบบนั้นเลย ฉันใช้มันเพื่อรับค่า tz จากฝั่งไคลเอนต์ แล้วแปลงเป็น UTC ทันทีที่มาถึง ถ้าจำเป็นต้องใช้ tz จริง ๆ ก็เก็บแยกต่างหาก ซึ่งเกิดขึ้นไม่บ่อย (เช่น ปฏิทินควรเก็บ tz แต่คงไม่จำเป็นต้องเก็บคู่กับ UTC ทุกค่า แค่อาจเก็บในระดับผู้ใช้ก็พอ อีกตัวอย่างคือการจัดตารางพนักงานที่ 8am-4pm หรือ 8pm-4am อาจมีความหมายต่างกันตามสถานที่ ซึ่งนั่นไม่ใช่ datetime อีกต่อไป แต่เป็นเวลาในเขตเวลานั้น)
  • ฉันใช้ Arrow เมื่ออยากได้อะไรที่มากกว่าพื้นฐานเล็กน้อย ไลบรารีนี้น่าสนใจทีเดียว ไม่ใช่เพราะครอบคลุมเคสขอบมากกว่า แต่เพราะมีทั้งโหมด Rustified และโหมด Python ล้วน ใช้ Whenever แล้วไม่ต้องกังวลเรื่องอื่น และเวลาอยากได้การจัดการ datetime ที่ดีกว่าในโปรเจกต์ก็ไม่ต้องย้อนกลับไปใช้ datetime อีก ใช้ได้แม้ในสภาพแวดล้อมที่ไม่มี Rust toolchain หรือมีปัญหากับมัน Kudos
  • ดูเหมือนเราควรสร้างชุดทดสอบระดับอุตสาหกรรม/ข้ามภาษา ที่ใช้ทดสอบไลบรารีวันที่/เวลา/ปฏิทินจำนวนมากได้ คล้าย browser acid test แต่โฟกัสเฉพาะฟังก์ชันพื้นฐาน ฉันชอบไลบรารีใหม่นี้ (ขอบคุณ) แต่ชื่อมันให้ความหมายตรงข้ามกับสิ่งที่เป็นจริง "Whenever" ฟังดูเหมือนแปลว่าไม่ใส่ใจ แต่จริง ๆ แล้วคงใช้เฉพาะตอนที่ใส่ใจเท่านั้น แล้วก็ Shakira, ฮ่า ๆ อืม pedantic ก็มีคนใช้ไปแล้ว Timely, precise, punctual, meticulous, ahorita, pronto อะไรทำนองนั้น ฉันชอบชื่อที่เกี่ยวกับเวลา สุดท้ายนี้ ไม่มีลิงก์ไหนในนี้พูดถึงความไม่เปลี่ยนรูปเลย ทั้งที่มันควรถูกพูดถึงไว้บนสุด