diff --git a/__main__.py b/__main__.py index 53c2c43..2723d1c 100644 --- a/__main__.py +++ b/__main__.py @@ -1,5 +1,19 @@ -def main() -> None: - print("Hello world") +from doomsday.algorithm import get_weekday_for_date +from doomsday.date import is_valid_date -main() +def main(): + while True: + user_input = input( + "Please enter a date using the format YYYY-MM-dd : ") + + # Check date input + if is_valid_date(user_input): + break + + print( + f"{user_input} was a {get_weekday_for_date(user_input)}") + + +if __name__ == "__main__": + main() diff --git a/doomsday/algorithm.py b/doomsday/algorithm.py index cf81d60..1ba4d3e 100644 --- a/doomsday/algorithm.py +++ b/doomsday/algorithm.py @@ -1,2 +1,63 @@ -def get_weekday_for_date(date: str) -> str: - return "Sunday" +from datetime import datetime + +WEEKDAYS = ( + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday' +) +# List of memorable dates that always land on doomsday for each month +# (except January and February) +doomsday_month: list[int] = [3, 28, 14, 4, 9, 6, 11, 8, 5, 10, 7, 12] + + +def get_weekday_for_date(date_str: str) -> str: + """ + Returns the day of the week for the given date in the format YYYY-MM-dd. + """ + # Convert date to datetime + date = datetime.strptime(date_str, '%Y-%m-%d') + # Get the doomsday of the year + doomsday_of_year = get_doomsday_year(date.year) + + # Check if the year is a leap year + # If it is, change the doomsday for January and February + if date.year % 400 == 0 or (date.year % 100 != 0 and date.year % 4 == 0): + doomsday_month[0] = 4 + doomsday_month[1] = 29 + + # Get the difference between the doomsday of the month and the given date + difference_doomsday_and_date = date.day - doomsday_month[date.month - 1] + + # Get the weekday of the date as an integer between 0 and 6 + weekday = (doomsday_of_year + difference_doomsday_and_date) % 7 + + # Return the weekday as a string + return WEEKDAYS[weekday] + + +def get_doomsday_year(year: int) -> int: + """Gets the doomsday of the year as an integer between 0 and 6""" + last_two_digits_of_year: int = year % 100 + + if last_two_digits_of_year % 2 != 0: + last_two_digits_of_year += 11 + last_two_digits_of_year //= 2 + if last_two_digits_of_year % 2 != 0: + last_two_digits_of_year += 11 + + # Get the difference between the last two numbers of the year and the + # closest superior or equal multiple of 7 + difference_multiple_of_7 = last_two_digits_of_year % 7 + if difference_multiple_of_7 != 0: + difference_multiple_of_7 = 7 - difference_multiple_of_7 + + # Number to add to the difference to get the doomsday of the year + numbers_to_add_by_century: list[int] = [2, 0, 5, 3] + + # Return the doomsday of the year as an integer between 0 and 6 + return (difference_multiple_of_7 + numbers_to_add_by_century[ + (year // 100) % 4]) % 7 diff --git a/doomsday/date.py b/doomsday/date.py index 0f8e737..e29521b 100644 --- a/doomsday/date.py +++ b/doomsday/date.py @@ -1,2 +1,30 @@ -def is_valid_date(date: str) -> bool: - return True +def is_valid_date(date_str: str) -> bool: + from datetime import datetime + + try: + date_obj: datetime = datetime.strptime(date_str, '%Y-%m-%d') + + # Check if the year is greater than or equal to 1583 + # If it is not, return False and print an error message + if date_obj.year < 1583: + print("The year must be greater than or equal to 1583.") + + return False + + return True + + # If the date is not in the correct format (YYYY-MM-dd) or if the date + # doesn't exist (for example : 2021-18-45), then return False and print + # an error message + except ValueError: + print( + f"Incorrect date {date_str}." + " Please use the format YYYY-MM-dd or check if the date exists.") + + return False + + except Exception as e: + # Handle any other exception + print(e) + + return False