เบื้องหลังการทำงานเหล่านี้ไม่ได้มาจากการนับไล่วันทีละวัน แต่เกิดจากสมการทางคณิตศาสตร์ที่ชื่อว่า Zeller’s Congruence (สูตรคอนกรูเอนซ์ของเซ็ลเลอร์) ซึ่งคิดค้นโดยนักคณิตศาสตร์ชาวเยอรมัน Christian Zeller ในศตวรรษที่ 19 ช่วยให้เราแปลง วัน-เดือน-ปี เป็นวันประจำสัปดาห์ได้อย่างแม่นยำ
กฎเหล็กข้อสำคัญก่อนเริ่มคำนวณ
ปฏิทินสากล (Gregorian Calendar) มีระบบ ปีอธิกสุรทิน (Leap Year) ซึ่งจะเพิ่มวันที่ 29 กุมภาพันธ์ เข้ามาทุกๆ 4 ปี เพื่อไม่ให้การคำนวณปฏิทินคลาดเคลื่อน สูตรของ Zeller จึงกำหนดเงื่อนไขพิเศษไว้ดังนี้
- เดือนมกราคม ให้นับเป็น เดือนที่ 13 ของปีก่อนหน้า
- เดือนกุมภาพันธ์ ให้นับเป็น เดือนที่ 14 ของปีก่อนหน้า
- เดือนมีนาคม ถึง ธันวาคม ให้นับเป็นเดือน 3 ถึง 12 ตามปกติ
ตัวอย่างการปรับค่า
หากต้องการคำนวณวันที่ 15 กุมภาพันธ์ 2024
คุณจะต้องปรับเป็น วันที่ 15 เดือน 14 ของปี 2023 แทน
สูตร Zeller’s Congruence (ปฏิทินเกรกอเรียน)
Plain Text
h = (q + floor(13*(m + 1)/5) + K + floor(K/4) + floor(J/4) - 2*J) mod 7
อธิบายความหมายของตัวแปร
| ตัวแปร | ความหมาย | ตัวอย่าง (1 ม.ค. 2000) |
|---|---|---|
| q | วันที่ของเดือน (Day) | 1 |
| m | ลำดับเดือน (มี.ค.=3, …, ม.ค.=13, ก.พ.=14) | 13 (เพราะเป็น ม.ค.) |
| Y | ปี ค.ศ. ที่ปรับแล้ว | 1999 (ลดลง 1 ปี) |
| K | สองหลักท้ายของปี (Y mod 100) | 99 |
| J | สองหลักแรกของปี หรือศตวรรษ (floor(Y / 100)) | 19 |
| floor(…) | ฟังก์ชันปัดเศษทิ้ง (หารเอาเฉพาะจำนวนเต็ม) | – |
| mod 7 | การหารเอาเศษด้วย 7 | เศษเหลือ 0 ถึง 6 |
ตารางถอดรหัสผลลัพธ์ (h)
เมื่อนำผลรวมทั้งหมดมาหารเอาเศษด้วย 7 จะได้ค่าตัวเลขระหว่าง 0 ถึง 6 ซึ่งเทียบเป็นวันในสัปดาห์ได้ตามตารางนี้
| ค่า h | วันในสัปดาห์ (ไทย) | วันในสัปดาห์ (อังกฤษ) |
|---|---|---|
| 0 | วันเสาร์ | Saturday |
| 1 | วันอาทิตย์ | Sunday |
| 2 | วันจันทร์ | Monday |
| 3 | วันอังคาร | Tuesday |
| 4 | วันพุธ | Wednesday |
| 5 | วันพฤหัสบดี | Thursday |
| 6 | วันศุกร์ | Friday |
ตัวอย่างการคำนวณจริงทีละขั้นตอน
โจทย์: วันที่ก้าวเข้าสู่วายทูเค 1 มกราคม ค.ศ. 2000 ตรงกับวันอะไร?
1. กำหนดค่าตัวแปร
- วันที่:
q = 1 - เดือนมกราคม:
m = 13 - ปรับปีถอยหลัง 1 ปี:
Y = 1999 - สองหลักท้ายของปี:
K = 99 - สองหลักแรกของปี:
J = 19
2. แทนค่าและคำนวณแต่ละพจน์
q = 1floor(13 × (13 + 1) / 5) = floor(182 / 5) = 36K = 99floor(99 / 4) = 24floor(19 / 4) = 4-2J = -2 × 19 = -38
3. รวมผลลัพธ์และหารเอาเศษ
ผลรวม = 1 + 36 + 99 + 24 + 4 - 38 = 126
นำมาหารเอาเศษด้วย 7: 126 mod 7 = 0
ผลลัพธ์ h = 0 เมื่อตรวจกับตารางจะตรงกับ “วันเสาร์”
โค้ดตัวอย่างสำหรับนำไปใช้งาน
1. ตัวอย่างภาษา Python
Plain Text
def get_day_of_week(day: int, month: int, year: int) -> str:
days = ["เสาร์", "อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัสบดี", "ศุกร์"]
# ปรับเดือนและปีสำหรับ ม.ค. และ ก.พ.
if month < 3:
month += 12
year -= 1
q = day
m = month
k = year % 100
j = year // 100
# คำนวณสูตร Zeller's Congruence
h = (q + (13 * (m + 1)) // 5 + k + (k // 4) + (j // 4) - (2 * j)) % 7
return days[h]
# ทดสอบรัน
print(get_day_of_week(1, 1, 2000)) # Output: เสาร์
2. ตัวอย่างภาษา JavaScript
Plain Text
function getDayOfWeek(day, month, year) {
const days = ["เสาร์", "อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัสบดี", "ศุกร์"];
if (month < 3) {
month += 12;
year -= 1;
}
const q = day;
const m = month;
const k = year % 100;
const j = Math.floor(year / 100);
let h = (q + Math.floor((13 * (m + 1)) / 5) + k + Math.floor(k / 4) + Math.floor(j / 4) - (2 * j)) % 7;
if (h < 0) h += 7; // ป้องกันกรณีเศษติดลบ
return days[h];
}
// ทดสอบรัน
console.log(getDayOfWeek(1, 1, 2000)); // Output: เสาร์
สรุป
สูตร Zeller’s Congruence เป็นหลักการคณิตศาสตร์ที่เรียบง่ายแต่ทรงพลัง เหมาะอย่างยิ่งสำหรับนำไปเขียนเป็นฟังก์ชันคำนวณปฏิทินในโปรเจกต์ หรือนำมาใช้ทายวันสนุกๆ โดยไม่ต้องพึ่งพาไลบรารีจัดการวันที่เพิ่มเติม