Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python Calendar Functions: firstweekday, leapdays, HTMLCalendar

บทความนี้ครอบคลุมฟังก์ชันขั้นสูงของโมดูล calendar ที่มีประโยชน์สำหรับการพัฒนาแอปพลิเคชันที่เกี่ยวข้องกับวันที่และปฏิทิน

1. firstweekday() และ setfirstweekday()

ควบคุมวันที่ถือเป็น "วันแรกของสัปดาห์" (Default: Monday = 0)

import calendar

print(f"Current first weekday: {calendar.firstweekday()}")  # 0 (Monday)

# เปลี่ยนเป็น Sunday (US Convention)
calendar.setfirstweekday(calendar.SUNDAY)
print(f"New first weekday: {calendar.firstweekday()}")  # 6 (Sunday)

# Constants
print(calendar.MONDAY)    # 0
print(calendar.TUESDAY)   # 1
print(calendar.SUNDAY)    # 6

2. leapdays(year1, year2)

นับจำนวน Leap Years ในช่วง [year1, year2) (Include year1, Exclude year2)

# Leap years 1980-2015
print(calendar.leapdays(1980, 2015))  # 9

# Verify: Leap years = 1980, 84, 88, 92, 96, 2000, 04, 08, 12
# 2000 is leap (divisible by 400), 1900 is not (divisible by 100 but not 400)

3. HTMLCalendar - สร้างปฏิทิน HTML

คลาสสำหรับ Generate HTML Calendar พร้อม CSS Classes

Basic Usage

import calendar

hc = calendar.HTMLCalendar(calendar.MONDAY)
html_output = hc.formatmonth(2024, 3, withyear=True)
print(html_output)

Output Structure

<table border="0" cellpadding="0" cellspacing="0" class="month">
  <tr><th colspan="7" class="month">March 2024</th></tr>
  <tr>
    <th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th>
    <th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th><th class="sun">Sun</th>
  </tr>
  <tr>
    <td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td class="noday">&nbsp;</td>
    <td class="fri">1</td><td class="sat">2</td><td class="sun">3</td><td class="mon">4</td>
  </tr>
  ...
</table>

CSS Classes สำหรับ Styling

ClassDescription
monthTable Wrapper
mon, tue, wed, thu, fri, sat, sunDay Headers และ Cells
nodayCells ไม่อยู่ในเดือนนี้
todayวันนี้ (ถ้าใช้ formatyear)

Custom HTMLCalendar

class ThaiHTMLCalendar(calendar.HTMLCalendar):
    """HTML Calendar ภาษาไทย พร้อม Buddhist Era"""
    
    thai_months = [
        '', 'มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน',
        'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'
    ]
    
    thai_days = ['จันทร์', 'อังคาร', 'พุธ', 'พฤหัสบดี', 'ศุกร์', 'เสาร์', 'อาทิตย์']
    
    def formatmonthname(self, theyear, themonth, withyear=True):
        if withyear:
            be_year = theyear + 543
            month_name = self.thai_months[themonth]
            return f'{month_name} {be_year}'
        return ''
    
    def formatweekheader(self):
        return '' + ''.join(f'{day}' 
                                for i, day in enumerate(self.thai_days)) + ''

# ใช้งาน
thai_cal = ThaiHTMLCalendar(calendar.MONDAY)
print(thai_cal.formatmonth(2024, 1))

4. TextCalendar - Text-based Calendar

tc = calendar.TextCalendar(firstweekday=calendar.SUNDAY)

# Format Month
print(tc.formatmonth(2024, 3))

# Format Year (Multi-month)
print(tc.formatyear(2024, width=3, l=1, c=6, m=3))

# Iterate Days
for day in tc.itermonthdays(2024, 3):
    print(day, end=' ')  # 0 = day not in month
print()

# Iterate Dates (datetime.date objects)
for d in tc.itermonthdates(2024, 3):
    print(d, end=' ')  # Includes days from prev/next month
print()

5. Calendar Base Class - Low-level Iterators

cal = calendar.Calendar(firstweekday=calendar.MONDAY)

# Iterate weeks as lists of dates
for week in cal.monthdatescalendar(2024, 3):
    print([d.strftime('%Y-%m-%d') for d in week])

# Iterate days as (day, weekday) tuples
for day, weekday in cal.itermonthdays2(2024, 3):
    if day != 0:
        print(f"Day {day}: Weekday {weekday}")

# Iterate weeks of year
for week in cal.yeardatescalendar(2024, width=3):
    # 3 months per row
    pass

6. ตัวอย่างประยุกต์: Event Calendar

from datetime import date
import calendar

class EventCalendar(calendar.HTMLCalendar):
    def __init__(self, events, firstweekday=0):
        super().__init__(firstweekday)
        self.events = events  # Dict: date -> list of events
    
    def formatday(self, day, weekday, themonth, theyear):
        if day == 0:
            return ' '
        
        current_date = date(theyear, themonth, day)
        events_today = self.events.get(current_date, [])
        
        event_html = ''
        if events_today:
            event_html = '
    ' for event in events_today: event_html += f'
  • {event}
  • ' event_html += '
' return f'{day}{event_html}' # ใช้งาน events = { date(2024, 3, 8): ["International Women's Day", "Meeting 10:00"], date(2024, 3, 17): ["St. Patrick's Day"], date(2024, 3, 29): ["Good Friday"], date(2024, 3, 31): ["Easter Sunday"], } ec = EventCalendar(events, calendar.MONDAY) print(ec.formatmonth(2024, 3))

สรุป

  • firstweekday()/setfirstweekday(): ควบคุมวันเริ่มสัปดาห์ (Mon vs Sun)
  • leapdays(): นับ Leap Years ในช่วง
  • HTMLCalendar: Generate HTML Calendar พร้อม CSS Classes สำหรับ Styling
  • TextCalendar: Text-based Calendar Formatting
  • Calendar Base Class: Low-level Iterators (itermonthdays, monthdatescalendar, etc.)
  • Extensible: สร้าง Subclass เพื่อ Customize Output (Thai Language, Events, etc.)