The date is March 24, 2437 and the the Earth has been nearly completely destroyed by the actions of its inhabitants. Our last hope in this disaster lies in a shabby time machine built from old toasters and used microwave parts.  

The World Time Agency requires you to travel back in time to prevent disaster.  You are ordered to "remove" certain babies from the timeline.  

Historical newspapers and records provide the Date, Month, and Year for each mission.  Unfortunately the time machine takes input only as the number of days to travel back in time.  It is your job to calculate how many days you will need to travel back from today's date (March 24, 2437) for each mission.

For example, if a historical newspaper says a dangerous baby was born on:
Date = 21, Month = 3, Year = 2437
Then your function must compute that it was 3 Days ago.

Another example would be that a baby born on Date = 24, Month = 3, Year = 2436 would have been born 365 days ago.

You will not have time travel past the year 0.

Note that while this is a fairly simple task, it is complicated by the fact that newspapers used the Julian calendar instead of the current Gregorian calendar prior to September 14, 1752.  In 1752, it was declared that Sep 2, 1752 was proceeded immediately by September 14, 1752, entirely omitting September 3-13. Furthermore, the rules for leap years changed on that date.

After 1752, leap years are on any year divisible by four, except for years which are divisible by 100. An exception to that exception is that years divisible by 400 are always leap years.  For example, 1803, 1900, 2001, 2019, and 2100 are not leap years, but 1804, 2000 and 2020 are leap years. 
However in the Julian calander prior to and including 1752, leap years were on every year divisible by 4, without the exception of years divisible by 100.  The years 1752, 1700, 1600, and 0 were all leap years.

Good luck agent, the world depends on you!


Note: It is not required, but if you find it helpful to visualize the switch from the Julian to the Gregorian calendar, please see these links:

Please observe that much of September 1752 is missing here: https://www.timeanddate.com/calendar/?year=1752&country=1

Please observe that 1700 is a leap year here: https://www.timeanddate.com/calendar/?year=1700&country=1

Source: codewars | Difficulty: EASY

Starter code: def days(date, month, year):
	

Solutions:
import datetime

def days(date, month, year):
	x = datetime.datetime(year, month, date)
	y = datetime.datetime(2437, 3, 24)
	delta = y - x
	t = delta.days
	if year < 1752 or (year == 1752 and month < 9) or (year == 1752 and month == 9 and (date < 14)):
		t -= 11
	if year < 1752:
		y = year // 4 * 4 + 4
		for i in range(y, 1752, 4):
			if i % 100 == 0 and i % 400 != 0:
				t += 1
	return t


my_year = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}

def is_leap(year):
	return [0, 1, 0, 1, 0, 1, 1, 1][(year % 4 == 0) + (year % 100 == 0) + (year % 400 == 0) + 4 * (year < 1752)]

def day_of_year(d, m, y=2437):
	return sum((my_year[i] for i in range(1, m))) + d + is_leap(y) * (m > 2)

def days(d, m, y, d0=24, m0=3, y0=2437):
	A = day_of_year(d0, m0)
	B = sum(map(is_leap, range(y + 1, y0))) + 365 * (y0 - y)
	C = 11 * (y < 1752 or (y == 1752 and day_of_year(d, m) < 246))
	D = is_leap(y) - day_of_year(d, m, y)
	return A + B - C + D


def is_leap_year(year):
	if year % 4 != 0:
		return False
	if year <= 1752:
		return True
	return year % 100 != 0 or year % 400 == 0
DOM = {1: 0, 2: 31, 3: 59, 4: 90, 5: 120, 6: 151, 7: 181, 8: 212, 9: 243, 10: 273, 11: 304, 12: 334}

def is_julian_period(date, month, year):
	if year > 1752:
		return True
	if year < 1752:
		return False
	if month < 9:
		return False
	if month > 9:
		return True
	return date >= 14

def normalized_day(date, month, year):
	orig_year = 0
	days = date + DOM[month] + (year - orig_year) * 365
	if is_leap_year(year) and month >= 3:
		days += 1
	for y in range(orig_year, year, 4):
		if is_leap_year(y):
			days += 1
	if is_julian_period(date, month, year):
		days -= 11
	return days

def days(date, month, year):
	return normalized_day(24, 3, 2437) - normalized_day(date, month, year)


def days(date, month, year):

	def day_calc(date, month, year):
		count = 0
		for i in range(0, year):
			if i < 1752:
				if i % 4 == 0:
					count += 366
				else:
					count += 365
			elif i == 1752:
				count += 366 - 11
			elif i % 400 == 0:
				count += 366
			elif i % 100 == 0:
				count += 365
			elif i % 4 == 0:
				count += 366
			else:
				count += 365
		months = {0: 0, 1: 31, 2: 59, 3: 90, 4: 120, 5: 151, 6: 181, 7: 212, 8: 243, 9: 273, 10: 304, 11: 334, 12: 365}
		if year % 400 == 0:
			count += months[month - 1]
			if month > 2:
				count += 1
		elif year % 100 == 0:
			count += months[month - 1]
		elif year % 4 == 0:
			count += months[month - 1]
			if month > 2:
				count += 1
		else:
			count += months[month - 1]
		if year == 1752 and month == 9 and (date > 13):
			count += date - 11
		else:
			count += date
		return count
	cdate = 24
	cmonth = 3
	cyear = 2437
	return day_calc(cdate, cmonth, cyear) - day_calc(date, month, year)
print(days(31, 1, 2436))


from datetime import *

def julian(day, month, year):
	dayy = (year - 1) * 365 + (year - 1) // 4
	daym = sum([0, 31, 29 if year % 4 == 0 else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][:month])
	return dayy + daym + day
ref = date(2437, 3, 24)
greg = date(1752, 9, 14)
days2greg = (ref - greg).days
jgreg = julian(3, 9, 1752)

def days(day, month, year):
	if year > 1752 or (year == 1752 and month > 9) or (year == 1752 and month == 9 and (day > 13)):
		return (ref - date(year, month, day)).days
	else:
		return jgreg - julian(day, month, year) + days2greg


def days(date, month, year):
	current_year = 2437
	current_month = 3
	current_date = 24
	current_days = 24 + 28 + 31
	days = 0
	y_days = 0
	print((date, month, year))

	def leap_year(year):
		condition = False
		if year > 1752:
			if year % 400 == 0:
				condition = True
			elif year % 100 == 0:
				condition = False
			elif year % 4 == 0:
				condition = True
		elif year % 4 == 0:
			condition = True
		return condition
	month_30 = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
	month_30_leap = {1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
	if year > 1752:
		if leap_year(year) == True:
			for m in range(1, month):
				days += month_30_leap[m]
			days += date
			for y in range(year, current_year):
				if leap_year(y) == True:
					y_days += 366
				else:
					y_days += 365
			days = current_days - days + y_days
			print('this one - 1')
			return days
		else:
			for m in range(1, month):
				days += month_30[m]
			days += date
			for y in range(year, current_year):
				if leap_year(y) == True:
					y_days += 366
				else:
					y_days += 365
			days = current_days - days + y_days
			print('this one = 2')
			return days
	elif year % 4 == 0:
		for m in range(1, month):
			days += month_30_leap[m]
		if year == 1752 and month > 9:
			days -= 11
		if year == 1752 and month == 9:
			for d in range(1, date + 1):
				if 3 > d or d > 13:
					print(d)
					days += 1
		else:
			days += date
		for y in range(year, current_year):
			if leap_year(y) == True:
				if y == 1752:
					y_days += 366 - 11
				else:
					y_days += 366
			else:
				y_days += 365
		days = current_days - days + y_days
		print('this one - 3')
		return days
	else:
		for m in range(1, month):
			days += month_30[m]
		days += date
		for y in range(year, current_year):
			if leap_year(y) == True:
				if y == 1752:
					y_days += 366 - 11
				else:
					y_days += 366
			else:
				y_days += 365
		days = current_days - days + y_days
		print('this one - 4')
		return days


def leap(year):
	if year < 1753:
		if year % 4 == 0:
			return True
	elif year % 4 == 0:
		if year % 100 != 0 or year % 400 == 0:
			return True
		elif year % 100 == 0:
			return False
	else:
		return False

def days(date, month, year):
	the_date = [24, 3, 2437]
	Leap_year = {1: 31, 2: 29, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
	Non_leap_year = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
	point_date = [date, month, year]
	reverse_date = [year, month, date]
	days_from_beginning = the_date[0]
	for i in range(1, the_date[1]):
		days_from_beginning += Non_leap_year[i]

	def to_year_end(list, dict):
		days_to_end = dict[list[1]] - list[0]
		for i in range(list[1] + 1, 13):
			days_to_end += dict[i]
		return days_to_end
	if year == the_date[2] and month == the_date[1]:
		result = the_date[0] - date
		return result
	elif year == the_date[2] and month < the_date[1]:
		result = days_from_beginning - date
		for i in range(1, month):
			result -= Non_leap_year[i]
		return result
	else:
		result = days_from_beginning
		if reverse_date < [1752, 9, 14]:
			result -= 11
		if leap(year):
			result += to_year_end(point_date, Leap_year)
		else:
			result += to_year_end(point_date, Non_leap_year)
		for y in range(year + 1, the_date[2]):
			if leap(y):
				result += 366
			else:
				result += 365
		return result


def days(date, month, year):

	def leap_year(y):
		if y % 4 == 0:
			if y > 1752 and y % 100 == 0:
				if y % 400 == 0:
					return True
				else:
					return False
			return True

	def days_in_years(y):
		n = 0
		for num in range(1, y):
			if leap_year(num):
				n += 1
		return (y - 1) * 365 + n if y <= 1752 else (y - 2) * 365 + n + 354

	def days_in_month(m, y):
		n = 0
		list_31 = [1, 3, 5, 7, 8, 10, 12]
		list_30 = [4, 6, 9, 11]
		for num in range(1, m):
			if num in list_31:
				n += 31
			elif num in list_30:
				n += 30
			elif leap_year(y):
				n += 29
			else:
				n += 28
		if y == 1752 and m > 9:
			n -= 11
		return n

	def days_in_days(d, m, y):
		if y == 1752 and m == 9 and (d > 2):
			return d - 11
		return d
	current_days = days_in_days(24, 3, 2437) + days_in_month(3, 2437) + days_in_years(2437)
	return current_days - (days_in_days(date, month, year) + days_in_month(month, year) + days_in_years(year))


def days(date, month, year):
	daysaway = 0
	monthdays = 0
	leapyear = 0
	monthsinyear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
	daysaway += 24 - date
	if year < 2437:
		daysaway += (2437 - year) * 365
	if month < 3:
		if month == 1:
			daysaway += monthsinyear[0] + monthsinyear[1]
		else:
			daysaway += monthsinyear[1]
	elif month > 3:
		for i in range(3, month):
			monthdays -= monthsinyear[i - 1]
		daysaway += monthdays
	if year < 1752 or (year == 1752 and month < 9) or (year == 1752 and month == 9 and (date < 3)):
		daysaway -= 11
	for i in range(year, 2438):
		if i <= 1752 and i % 4 == 0:
			leapyear += 1
			if i == year and month > 2:
				leapyear -= 1
		elif i > 1752:
			if i % 400 == 0 or (i % 4 == 0 and i % 100 != 0):
				leapyear += 1
				if i == year and month > 2:
					leapyear -= 1
	daysaway += leapyear
	return daysaway


from datetime import date
GREG_START = date(1752, 9, 14)
GREG_SKIP = 11
CURR_DATE = date(2437, 3, 24)

def days(day, month, year):
	try:
		target_date = date(year, month, day)
		distance = (CURR_DATE - target_date).days
	except ValueError:
		target_date = date(year, month, day - 1)
		distance = (CURR_DATE - target_date).days - 1
	if target_date < GREG_START:
		distance -= GREG_SKIP
		distance += len([cent for cent in range((year - 1) // 100 + 1, GREG_START.year // 100 + 1) if cent % 4])
	return distance