Menu

Monday, August 14, 2017

[NodeJS] การแปลงวันที่จาก ค.ศ. เป็น พ.ศ. หรือจาก พ.ศ. เป็น ค.ศ.
[NodeJS] How to Convert Date from A.D. to B.E. or from B.E. to A.D.

ถ้าจะกล่าวถึง Library ที่เกี่ยวกับวันที่และเวลาสำหรับ NodeJS หลายๆคนคงคิดถึง momentjs งานนี้ก็เช่นกัน ด้วยการที่คิดว่าการแปลงปี ค.ศ. เป็น พ.ศ. สลับไปมา มันก็แค่เพิ่มหรือลบปีไป 543 ปีเท่านั้น

สมมติว่า dateStr เป็นวันที่ที่เป็นปี ค.ศ. ที่จะแปลงเป็นปี พ.ศ. ก็จะได้โค้ดประมาณนี้
let date = moment(dateStr, 'DD/MM/YYYY');
if (date.isValid()) {
    date.add(543, 'years');
    return date.format('DD/MM/YYYY');
}
หรือ
let date = moment(dateStr, 'DD/MM/YYYY');
if (date.isValid()) {
    date.subtract(543, 'years');
    return date.format('DD/MM/YYYY');
}
แต่งานนี้ก็ไม่ผ่าน Tester ฝีมือดีของเรา เมื่อ Tester ทำการทดสอบด้วยวันที่ 29 กุมภาพันธ์ของปีที่เป็น Leap year

กรณีที่ต้องการแปลงจาก ค.ศ. เป็น พ.ศ. ยกตัวอย่างเช่น 29 กุมภาพันธ์ ค.ศ. 1968 (29/02/1968) เมื่อทำการแปลงตามโค้ดข้างต้น สิ่งที่คาดหวังคือ 29 กุมภาพันธ์ พ.ศ. 2511 แต่สิ่งที่ได้ไม่เป็นเช่นนั้น

กรณีที่ต้องการแปลงจาก พ.ศ. เป็น ค.ศ. ยกตัวอย่างเช่น 29 กุมภาพันธ์ พ.ศ. 2511 (29/02/2511) เมื่อทำการแปลงตามโค้ดข้างต้น สิ่งที่คาดหวังคือ 29 กุมภาพันธ์ ค.ศ. 1968 แต่สิ่งที่ได้ คือ Invalid date

ทั้งสองกรณีเกิดจาก momentjs จะทำการแปลงวันที่ในรูปแบบปี ค.ศ. เท่านั้น โค้ดข้างต้นจึงเป็นการบวกลบปี ค.ศ. เพียงเท่านั้น ไม่ใช่การแปลงเป็นปี พ.ศ. แต่อย่างใด

หลังจากนั้น ก็ต้องเปลี่ยนวิธีการแปลงปีเป็นแบบข้อความแทน โดยใช้ Regular Expression ก็จะได้โค้ดตามด้านล่าง
const DATE_REGEXP: RegExp = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])/(0?[1-9]|1[0-2])/([0-9]{4})$', 'gi');
dateStr = dateStr.replace(DATE_REGEXP,
    (str: string, day: string, month: string, year: string) => {
        return `${day}/${month}/${parseInt(year, 10) + 543}`;
});
หรือ
const DATE_REGEXP: RegExp = new RegExp('^(0?[1-9]|[1-2][0-9]|3[0-1])/(0?[1-9]|1[0-2])/([0-9]{4})$', 'gi');
dateStr = dateStr.replace(DATE_REGEXP,
    (str: string, day: string, month: string, year: string) => {
        return `${day}/${month}/${parseInt(year, 10) - 543}`;
});
ปล. งานนี้ต้องขอบคุณ Tester เป็นอย่างมากที่คิดเคสได้รอบครอบขนาดนี้ ถ้าทดสอบด้วยวันที่อื่นคงไม่มีทางเจอบั๊กตัวนี้แน่นอน (โอกาสมีเพียงหนึ่งวันในสี่ปีเท่านั้น)

No comments:

Post a Comment