Search code examples
pythondays

How to calculate when one's 10000 day after his or her birthday will be


I am wondering how to solve this problem with basic Python (no libraries to be used): How can I calculate when one's 10000 day after their birthday will be (/would be)?

For instance, given Monday 19/05/2008, the desired day is Friday 05/10/2035 (according to https://www.durrans.com/projects/calc/10000/index.html?dob=19%2F5%2F2008&e=mc2)

So far I have done the following script:

years = range(2000, 2050)
lst_days = []
count = 0
tot_days = 0
for year in years:
    if((year % 400 == 0) or  (year % 100 != 0) and  (year % 4 == 0)):
        lst_days.append(366)
    else:
        lst_days.append(365)
while tot_days <= 10000:
        tot_days = tot_days + lst_days[count]
        count = count+1
print(count)

Which estimates the person's age after 10,000 days from their birthday (for people born after 2000). But how can I proceed?


Solution

  • Using base Python packages only

    On the basis that "no special packages" means you can only use base Python packages, you can use datetime.timedelta for this type of problem:

    import datetime
    
    start_date = datetime.datetime(year=2008, month=5, day=19)
    
    end_date = start_date + datetime.timedelta(days=10000)
    
    print(end_date.date())
    

    Without any base packages (and progressing to the problem)

    Side-stepping even base Python packages, and taking the problem forwards, something along the lines of the following should help (I hope!).

    Start by defining a function that determines if a year is a leap year or not:

    def is_it_a_leap_year(year) -> bool:
        """
        Determine if a year is a leap year
    
        Args:
            year: int
    
        Extended Summary:
            According to:
                https://airandspace.si.edu/stories/editorial/science-leap-year
            The rule is that if the year is divisible by 100 and not divisible by
            400, leap year is skipped. The year 2000 was a leap year, for example,
            but the years 1700, 1800, and 1900 were not.  The next time a leap year
            will be skipped is the year 2100.
        """
        if year % 4 != 0:
    
            return False
    
        if year % 100 == 0 and year % 400 != 0:
    
            return False
    
        return True
    

    Then define a function that determines the age of a person (utilizing the above to recognise leap years):

    def age_after_n_days(start_year: int,
                         start_month: int,
                         start_day: int,
                         n_days: int) -> tuple:
        """
        Calculate an approximate age of a person after a given number of days,
        attempting to take into account leap years appropriately.
    
        Return the number of days left until their next birthday
    
        Args:
            start_year (int): year of the start date
            start_month (int): month of the start date
            start_day (int): day of the start date
            n_days (int): number of days to elapse
        """
    
        # Check if the start date happens on a leap year and occurs before the
        # 29 February (additional leap year day)
        start_pre_leap = (is_it_a_leap_year(start_year) and start_month < 3)
    
        # Account for the edge case where you start exactly on the 29 February
        if start_month == 2 and start_day == 29:
    
            start_pre_leap = False
    
        # Keep a running counter of age
        age = 0
    
        # Store the "current year" whilst iterating through the days
        current_year = start_year
    
        # Count the number of days left
        days_left = n_days
    
        # While there is at least one year left to elapse...
        while days_left > 364:
    
            # Is it a leap year?
            if is_it_a_leap_year(current_year):
    
                # If not the first year
                if age > 0:
    
                    days_left -= 366
    
                # If the first year is a leap year but starting after the 29 Feb...
                elif age == 0 and not start_pre_leap:
    
                    days_left -= 365
    
                else:
    
                    days_left -= 366
    
            # If not a leap year...
            else:
    
                days_left -= 365
    
            # If the number of days left hasn't dropped below zero
            if days_left >= 0:
    
                # Increment age
                age += 1
    
                # Increment year
                current_year += 1
    
        return age, days_left
    

    Using your example, you can test the function with:

    age, remaining_days = age_after_n_days(start_year=2000, start_month=5, start_day=19, n_days=10000)
    

    Now you have the number of complete years that will elapse and the number of remaining days

    You can then use the remaining_days to work out the exact date.