21. Порядковая дата в григорианский календарь.
Условие:
Разработайте функцию, принимающую в качестве параметра порядковую дату, включающую в себя год и день по порядку.
В качестве результата функция должна возвращать день и месяц, соответствующие переданной порядковой дате. Убедитесь, что ваша функция корректно обрабатывает високосные годы.
Для начала должен производиться запрос года и порядковой даты у пользователя. После этого программа должна вычислить реальную дату и вывести её на экран.
Код:
import my_lib # импорт самописной библиотеки
# ввод данных
while True:
try:
year = input("%75s" % "Введите год (в формате 2023): ")
year = int(year)
day = input("%75s" % "Введите порядковый номер дня в году: ")
day = int(day)
result = my_lib.digit_date_of_year(year, day) # на выходе кортеж из 2 элементов, результат функции из самописной библиотеки, первый элемент это флаг проверки существуте дата или нет (True/False) (с учётом високосного года), а второй элемент это реальная дата
if result[0]:
break
except:
print("%74s" % "Вы ввели не цифры или несуществующий номер дня в году.")
print("%74s" % "Дата:", result[-1])
Код библиотеки:
# определяет дату по номеру дня в году
def our_date(leap, day):
dict_1 = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31} # словарь для обычного года
dict_2 = {1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31} # словарь для високосного года
dict_1_mod = dict() # составим более интересный словарь, где значением ключа (месяца) является range из порядковых номеров в году
dict_2_mod = dict() # -||-
if leap: # определение даты для високосного года
temp_1 = 1
temp_2 = 1
for a, b in dict_2.items():
temp_2 += b
dict_2_mod[a] = range(temp_1, temp_2)
temp_1 += b
max_of_last_month = 0
for a, b in dict_2_mod.items():
if day in b:
result = str(a) + "-" + str(day - max_of_last_month)
max_of_last_month = max(b)
else: # определение даты для не високосного года
temp_1 = 1
temp_2 = 1
for a, b in dict_1.items():
temp_2 += b
dict_1_mod[a] = range(temp_1, temp_2)
temp_1 += b
max_of_last_month = 0
for a, b in dict_1_mod.items():
if day in b:
result = str(a) + "-" + str(day - max_of_last_month)
max_of_last_month = max(b)
return result
# возвращает кортеж с двумя элементами, где первый элемент - это True или False (определяет существует такая дата или нет), а второй элемент - это реальная дата (определение даты переадресована в другую функцию)
def digit_date_of_year(year, day):
if (((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)) == False) and (day > 365 or day < 1):
flag = False
number = 0
elif ((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)) and (day > 366 or day < 1):
flag = False
number = 0
elif ((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)):
flag = True
leap = True
number = our_date(leap, day)
elif (((year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 and year % 400 == 0)) == False):
flag = True
leap = False
number = our_date(leap, day)
return (flag, (str(year) + "-" + number)) # возвращаем кортеж, первый элемент которого является флагом прошла дата проверку на существование или нет, а второй элемент это реальная дата