Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion __main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
from doomsday.date import is_valid_date
from doomsday.algorithm import get_weekday_for_date


def main() -> None:
print("Hello world")
"""Main function asking for a date and displaying its day"""

date: str = ask_for_valid_date()

display_weekday_for_date(date, get_weekday_for_date(date))


def ask_for_valid_date() -> str:
"""Ask for a date until a valid one is given"""

given_date: str = ""

while True:
given_date = input("Your date (YYYY-MM-dd):\n")
if is_valid_date(given_date):
return given_date


def display_weekday_for_date(date: str, day: str) -> None:
"""Display a sentence saying a date and its day"""

print(f"{date} is a {day}")


main()
75 changes: 74 additions & 1 deletion doomsday/algorithm.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,75 @@
from doomsday.date import is_leap_year

DAYS = (
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
)

CENTURY_ANCHOR = (
3, 2, 0, 5
)


def get_weekday_for_date(date: str) -> str:
return "Sunday"
"""Return the name of the day corresponding to the given date"""

year, month, day = (value for value in date.split("-"))
anchor_day: int = get_anchor_day(year)

return get_weekday_by_anchor_day(
int(year), int(month), int(day), anchor_day)


def get_anchor_day(year: str) -> int:
"""Return the anchor day for the given year"""

# Get the last two numbers in the year
anchor_day: int = int(year[-2:len(year)])
century: int = int(year[0:-2]) + 1

if anchor_day % 2 != 0:
anchor_day += 11

anchor_day //= 2

if anchor_day % 2 != 0:
anchor_day += 11

# Find the lowest multiple of seven greater than the value we have,
# and keep the difference between this multiple and our value
anchor_day %= 7
anchor_day -= 7
anchor_day = -anchor_day

anchor_day += CENTURY_ANCHOR[(century % 4)]

return anchor_day % 7


def get_weekday_by_anchor_day(
year: int, month: int, day: int, anchor_day: int) -> str:
"""Return the weekday of the given MM-dd
with the anchor day for the year"""

is_leap_year_value: bool = is_leap_year(year)

doomsdays = [
3 if not is_leap_year_value else 4,
28 if not is_leap_year_value else 29,
14, 4, 9, 6, 11, 8, 5, 10, 7, 12
]

doomsday: int = doomsdays[month - 1]

if doomsday == day:
return DAYS[anchor_day]

if day > doomsday:
return DAYS[(anchor_day + (day - doomsday)) % 7]

return DAYS[(anchor_day - (doomsday - day)) % 7]
59 changes: 59 additions & 0 deletions doomsday/date.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,61 @@
DAYS_PER_MONTH = (
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
)


def is_valid_date(date: str) -> bool:
"""Check if a date is valid. Which means beign 3 numbers separated by "-",
and that the year, month and day given exist in the Gregorian calendar"""

if not is_valid_format_date(date):
return False

year, month, day = (int(value) for value in date.split("-"))

if year < 1583:
print("Years begin from 1583")
return False

if (1 > month) or (month > 12):
print("Month goes from 1 to 12")
return False

days_in_this_month: int = get_days_in_month(year, month)

if (1 > day) or (day > days_in_this_month):
print("For this month, day goes from 1 to ", days_in_this_month)
return False

return True


def is_valid_format_date(date: str) -> bool:
"""Verify if a given date is 3 numbers separated by "-" """

splited_date: list[str] = date.split("-")

if len(splited_date) != 3:
print("Date format should be YYYY-MM-dd")
return False

for part in splited_date:
if not part.isdigit():
print("A date must be composed with numbers")
return False

return True


def get_days_in_month(year: int, month: int) -> int:
"""Return the number of days in a month, depending on year"""

if month == 2:
return 28 if not is_leap_year(year) else 29

return DAYS_PER_MONTH[month-1]


def is_leap_year(year: int) -> bool:
"""Verify if a year is a leap year or not"""

return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)