Coding Study/Python Project

[Python Project] 달력 만들기

김 도경 2024. 10. 16. 17:17

[2024.10.16] 필수 온라인 강의 Part1 파이썬 라이브러리 활용 프로젝트 CH03 [날짜] 파이썬으로 달력만들기

프로젝트 개요
  • 달력만들기에 필요한 요소들
    - 윤년 확인            : calendar.isleap
    - 마지막 날짜 계산 : strptime
    - 지나온 날짜 계산 : dateutil
    - 요일 반환            : datetime
날짜 및 요일 계산
  • datetime : 시간을 다룰 때 가장 많이 상요하는 모듈
     - 날짜와 시간 데이터를 처리하는 파이썬 내장 라이브러리
     - 현재 시간에 대한 정보를 가져와, 원하는 형식으로 지정하여 사용할 수 있음
     - timedelta 객체를 활용해서 날짜/시간 연산이 가능하게 함

  • 날짜 표현
import datetime 
day1 = datetime.date(2022, 10, 15)                   #datetime.date모듈, day1에 저장
  • 날짜/시간 동시 표현
day2 = datetime.datetime(2022, 10, 15, 16, 10, 30)      #datetime.datetime모듈, day2에 저장
  • 각각의 소스 뽑기 가능
day2                     # datetime.datetime(2022, 10, 15, 16, 10, 30)

day2.year  # 연도
day2.month  # 월
day2.month  # 월
day2.hour  # 시간
day2.minute  # 분
day2.second  # 초

 

  • 날짜/시간 합치기도 가능
day = datetime.date(2022, 10, 15)
time = datetime.time(16, 10, 30)

dt = datetime.datetime.combine(day, time)

 

  • 현재 날짜/시간 알기
datetime.date.today()               # 오늘 날짜 : datetime.date(2022, 9, 18)
datetime.datetime.now()             # 오늘 날짜+시간 :  datetime.datetime(2022, 9, 18, 11, 35, 5, 162865)

 

  • 날짜 계산 : timedelta
day1 = datetime.date(2022, 10, 15)
day2 = datetime.date(2022, 11, 10)

diff = day2 - day1                     # 날짜 뺄셈 , datetime.timedelta(days=26) 출력

# 날짜 덧셈
plus = datetime.timedelta(days=100)
add = day1 + plus                       # datetime.date(2023, 1, 23) 출력

 

  • 요일 판별
    - 월요일(0), 화요일(1), 수요일(2), 목요일(3), 금요일(4), 토요일(5), 일요일(6)
day1 = datetime.date(2022, 10, 15)
day2 = datetime.date(2022, 11, 10)

day1.weekday()            # 5 출력 : 토요일 
day2.weekday()            # 3 출력 : 목요일

 

윤년 확인
  • 윤년 : 4 년마다 돌아오는 2월이 29일까지 인 해
     - 연도가 4로 나누어 떨어진다, 100으로 나누어 떨어지는 경우는 제외하고, 400으로 나누어 떨어지는 건 포함한다
     - (year % 4 ==0) and (year % 100 != 0) or (year % 400 == 0)
def isLeapYear(year): # 윤년이면 True, 아니면 False 를 출력하는 함수.
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
    
isLeapYear(2022)           # False
isLeapYear(2024)           # True

 

  • calender 라이브러리
import calendar

calendar.isleap(2022)            #캘린더 라이브러리에서 제공하는 isleap 모듈을 사용해도 나옴

calendar.leapdays(1990, 2022)    # 윤년 횟수, 두 년도 사이에 몇번의 윤년?

calendar.weekday(2022, 10, 15)   # 요일 반환

print(calendar.calendar(2022))   # 달력 출력

 

날짜 출력
import datetime

str_datetime = '2021-04-08 21:31:48'  # 날짜 형식 문자열, 정해놓은 규칙
currdate = datetime.datetime.strptime(str_datetime, '%Y-%m-%d %H:%M:%S')   # 규칙을 바꿀 수 있음, 파싱하기

type(currdate)                  # -> datetime.datetime 출력
currdate                        # datetime.datetime(2021, 4, 8, 21, 31, 48) 출력

 

  • strftime - 날짜와 시간(datetime) 을 문자열로 출력 : strptime 와 반대라고 생각하면 됨
import datetime
now = datetime.datetime.now()        # -> datetime.datetime(2024, 10, 16, 13, 51, 14, 53649) 출력

date = now.strftime('%Y-%m-%d')      # -> '2024-10-16' 출력
type(date)                           # -> str 출력
time = now.strftime('%H:%M:%S')
type(time)                # '13:51:14'출력

datetime = now.strftime('%Y-%m-%d %H:%M:%S')
type(datetime)                   # str

datetime                         # '2024-10-16 13:51:14' 출력

 

그 외 시간관련 라이브러리
  • dateutil : `parse` 함수를 통해 자동으로 날짜 형식을 찾아서 datetime 객체로 변환함

    - 사용을 안 한 경우
import datetime

date = '2022-10-15'
date_parsed = datetime.datetime.strptime(date, '%Y-%m-%d')        # strptime 활용
date_parsed                              # datetime.datetime(2022, 10, 15, 0, 0) 출력됨


- 사용을 한 경우

from dateutil.parser import parse

parse(date)                # datetime.datetime(2022, 10, 15, 0, 0) 출력
parse("Oct 15, 2022 04:05:32 PM")       # 자동 형식 탐지

log = 'INFO 2022-01-01T00:00:01 Happy new year, human.'       # 날짜 문자열 자동 탐자
parse(log, fuzzy=True)                # datetime.datetime(2022, 1, 1, 0, 0, 1) 출력
  • time
    - `datetime` 라이브러리와 같이 파이썬에서 시간과 날짜를 다루기 위한 내장 라이브러리
    - 프로그램 실행 경과 시간, 프로그램 대기 시간 등을 만들 때 주로 사용

- 타임 함수를 현재 시간을 불러오기

import time

time.time()                # 현재 시간 출력 (실수형) , 1729058624.712468으로 출력

time.ctime()               # 현재 시간 출력 (문자형), 'Wed Oct 16 15:04:01 2024'으로 출력

 

- 대기 시간 만들기 가능 : 3초 뒤에 두번째 문장 출력

# 대기 시간 생성
print('바로 출력되는 구문')

time.sleep(3)

print('3초후 출력되는 구문')

 

- 경과 시간 출력

start_time = time.time()

for i in range(5):
    time.sleep(1) # 1초간 대기               #대기 시간 출력
    print('반복 횟수', i+1)
    
end_time = time.time()
elapsed_time = end_time - start_time

print('경과 시간은 : {} 초 입니다 !'.format(elapsed_time)) #경과 시간 출력

 

미니 프로젝트 실습
파이썬으로 달력 만들기
윤년 판별 함수
  • 윤년 판별 공식에 따라 작동하는 함수 만들기
def isLeapYear(year): # 윤년이면 True, 아니면 False 를 출력하는 함수.
    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0
    
isLeapYear(2020)                # True
isLeapYear(2022)                # False
  • calendar 모듈 활용하기
import calendar

calendar.isleap(2020)        # True
calendar.isleap(2022)        # False

 

마지막 날짜 계산
  • lastDay 인수로 년, 월을 넘겨받아 그 달의 마지막 날짜를 리턴하는 함수
def lastDay(year, month) :
    # 각 달의 마지막 날짜를 기억하는 리스트 만들기
    m = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
   
    # 2월의 마지막 날짜를 확정 => 윤년이면 29일로 수정
    if isLeapYear(year):
            m[1] = 29 

    return m[month - 1]  # 마지막 날짜 리턴

- 1월부터 12월까지 마지막 날짜가 다 다름

지나온 날짜 계산
  • totalDay 년, 월, 일을 넘겨받아 1년 1월 1일 부터 지난 날짜의 합계를 리턴하는 함수
  • total 계산 순서
       - 평년을 기준으로 전년도까지 일자 합계 -> 윤년이었던 횟수 더하기
       - 전달까지 해당 연도 일자 더하기
       - 이번달 날짜 더하기
def totalDay(year, month, day):
    # 1년 1월 1일 부터 전 년도 12월 31일 까지 지난 날짜를 합산
    total = (year - 1) * 365 + (year - 1) // 4 - (year - 1) // 100 + (year - 1) // 400
    
    # 전년도 까지 지난 날짜의 합계에 전 달까지 지난 날짜 더하기
    for i in range(1, month):
        total += lastDay(year, i)  # 윤년 확인 포함

    return total + day # 전달 까지 지난 날짜에 이번달 날짜를 더해서 리턴ㅍ

 

요일 반환
  • weekDay 인수로 년, 월, 일을 넘겨받아 요일을 계산해 숫자로 리턴하는 함수
  • 1년 1월 1일 부터 인수로 넘겨받은 년, 월, 일 까지 지난 날짜의 합계를 7로 나눈 나머지 반환
  • 일요일(0), 월요일(1), 화요일(2), 수요일(3), 목요일(4), 금요일(5), 토요일(6)
def weekDay(year, month, day):
    return totalDay(year, month, day) % 7

 

달력 확인
if __name__ == "__main__":
    
    # 달력 프로그램 도입부
    year, month = map(int, input('달력을 출력할 년, 월을 입력하세요 : ').split())
    print('=' * 28)
    print('         {0:4d}년{1:2d}월'.format(year, month))
    print('=' * 28)
    print(' 일  월  화  수  목  금  토 ')
    print('=' * 28)  

    # 1일이 출력될 요일의 위치를 맞추기 위해서 1일의 요일만큼 반복하며 빈칸을 출력
    for i in range(weekDay(year, month, 1)):        
        print('    ', end = '')

    # 1일 부터 달력을 출력할 달의 마지막 날짜까지 반복하며 달력을 출력
    for i in range(1, lastDay(year, month) + 1):
        print(' {0:2d} '.format(i), end = '') 


        # 출력한 날짜(i)가 토요일이고 그 달의 마지막 날짜가 아니면 줄바꿈
        if weekDay(year, month, i) == 6 and i != lastDay(year, month):
            print()


    print('\n' + '=' * 28) # 달력 하단

'Coding Study > Python Project' 카테고리의 다른 글

[Python Project] 뉴스기사 3줄 요약하기  (11) 2024.10.16