PlusMagi's Blog By Pitt Phunsanit Technology เคยสงสัยไหมว่า คอมพิวเตอร์หรือระบบปฏิทินรู้ได้อย่างไรว่า วันที่ 1 มกราคม ค.ศ. 2000 ตรงกับ “วันเสาร์” หรือวันเกิดของคุณเมื่อ 20 ปีก่อนตรงกับวันอะไรในสัปดาห์?

เคยสงสัยไหมว่า คอมพิวเตอร์หรือระบบปฏิทินรู้ได้อย่างไรว่า วันที่ 1 มกราคม ค.ศ. 2000 ตรงกับ “วันเสาร์” หรือวันเกิดของคุณเมื่อ 20 ปีก่อนตรงกับวันอะไรในสัปดาห์?

เบื้องหลังการทำงานเหล่านี้ไม่ได้มาจากการนับไล่วันทีละวัน แต่เกิดจากสมการทางคณิตศาสตร์ที่ชื่อว่า 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 = 1
  • floor(13 × (13 + 1) / 5) = floor(182 / 5) = 36
  • K = 99
  • floor(99 / 4) = 24
  • floor(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 เป็นหลักการคณิตศาสตร์ที่เรียบง่ายแต่ทรงพลัง เหมาะอย่างยิ่งสำหรับนำไปเขียนเป็นฟังก์ชันคำนวณปฏิทินในโปรเจกต์ หรือนำมาใช้ทายวันสนุกๆ โดยไม่ต้องพึ่งพาไลบรารีจัดการวันที่เพิ่มเติม


Exit mobile version