파이썬 날짜 입력 시 요일 구하는 코드

조회수 3069회

파이썬에서 날짜(yyyy.mm.dd)를 입력 시 요일을 구하는 코드에서 2021년 4월 1일을 입력하면 목요일이 아닌 금요일이라고 출력됩니다. 다수 출력을 해 본 결과 1900년 2월 28일까지는 정상적으로 출력되는데, 1900년 2월 29일을 인식하면서 1900년 3월 1일부터 요일이 +1이 되는 것을 확인했습니다. 왜 그런지, 또한 이걸 해결하려면 어떻게 수정해야 할지 알 수 있을까요?

year=int(input(">> year : "))
month=int(input(">> month : "))
date=int(input(">> date : "))

days=0

month_days=[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

for i in range(1, year):
         if i%4==0 or i%400==0 and i%100!=0:
             days=days+366
         else:
             days=days+365

for i in range(1, month):
    days=days+month_days[i-1]

if month>=3:
    if year%4==0 or year%400==0 and year%100!=0:
        days=days+1
    else:
        days=days

days=days+date

print(days)

if days%7==1:
    print(">> {}년 {}월 {}일은 월요일이다.".format(year, month, date))
elif days%7==2:
    print(">> {}년 {}월 {}일은 화요일이다.".format(year, month, date))
elif days%7==3:
    print(">> {}년 {}월 {}일은 수요일이다.".format(year, month, date))
elif days%7==4:
    print(">> {}년 {}월 {}일은 목요일이다.".format(year, month, date))
elif days%7==5:
    print(">> {}년 {}월 {}일은 금요일이다.".format(year, month, date))
elif days%7==6:
    print(">> {}년 {}월 {}일은 토요일이다.".format(year, month, date))
elif days%7==0:
    print(">> {}년 {}월 {}일은 일요일이다.".format(year, month, date))

1 답변

  • 직접 코딩해보니 좀 tricky한 아이디어가 두 가지 있네요.

    1. 입력받는 yearmonth에서는 1씩 빼셔야 합니다.

    왜냐하면, 예컨대

    서기 1년 1월 1일에서 서기 3년 7월 16일이 되기까지는:

    • 일단 2년이 지나가야 하고
    • 그 다음 6개월이 지나가야 하며
    • 그 후에 16일이 더 지나가야

    되기 때문입니다.

    이 부분 반드시 이해해 주세요. 지금 요일을 구하기 위해 날 수의 차이(diff)를 구하는 방식으로 접근하고 계시기 때문에 이 부분 중요합니다. 저도 왜안되지 왜안되지 하다가 곰곰이 생각해보니 얘기가 이렇게 되더라고요.

    2. 윤년을 고려하여 날 수를 구하기 위해 for를 순회하실 필요는 없습니다.

    정의에 따르면:

    • 서력 기원 연수가 4로 나누어 떨어지는 해는 윤년으로 한다.
    • 서력 기원 연수가 4, 100으로 나누어 떨어지는 해는 평년으로 한다.
    • 서력 기원 연수가 4, 100, 400으로 나누어 떨어지는 해는 윤년으로 둔다.

    그렇다면 그냥 이런 코드로 단순 곱셈 덧셈을 해내면 됩니다.

    import math
    
    diff = year * 365
    diff = diff + int(math.floor(year / 4))
    diff = diff - int(math.floor(year / 100))
    diff = diff + int(math.floor(year / 400))
    

    아무튼 그래서 제가 작성한 코드는 다음과 같습니다.
    적당한 year, month, day 인자를 넣고 실행해 보시면 파이썬의 datetime 라이브러리와 함께 대조해서 보실 수 있습니다.

    import math
    import datetime
    
    def getWeekdayStr(weekdayIndex) :
        weekdays = ['mon', 'tue', 'wed', 'thr', 'fri', 'sat', 'sun']
        return weekdays[weekdayIndex]
    
    def getWeekday(year, month, day) :
        monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        year = year - 1
        month = month - 1
        diff = year * 365
        diff = diff + int(math.floor(year / 4))
        diff = diff - int(math.floor(year / 100))
        diff = diff + int(math.floor(year / 400))
        for i in range(0, month) :
            diff = diff + monthDays[i]
        diff = diff + day
        diff = diff - 1 # '차이'를 구하고 있으므로 1을 빼야 아래의 mod 연산이 정확히 동작함
        print('weekday seems like: ' + str(diff % 7))
        return getWeekdayStr(diff % 7)
    
    print(getWeekday(2017, 7, 1))
    print('weekday really is: ' + str(datetime.date(2017, 7, 1).weekday()))
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)