"`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}"Vžežfžg)IŽª+·÷ÄF©IdiY.V‹i®¬>0ë®1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝëć©ić©i<D_-12š31šë®<šDY.Všë®<š]θ
Here we go again..
Try it online or try it only with custom specified starting date. (Pretty slow for large inputs, so won't be able to output the larger test cases with the current date.)
Explanation:
Since 05AB1E doesn't have any date builtins (except for the current day/time), I've calculated things manually before. I've used the code of going to the next day from this answer of mine, which in turns also uses the leap year calculation of this answer of mine.
Since this challenge also asks to go back in time, I've modified the program accordingly to support that as well.
Step 1: Create a function to calculate the amount of days in a month for a given year/month:
"`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}" # Push this string
V # Pop and store it in variable `Y`
` # Pop the list and push all values separated to the stack
# (the year will be at the top; month below it)
т‰ # Take the divmod-100 of the year
0K # Remove the 0s
θ # Pop and push its last item
4Ö # Check if it's divisible by 4
U # Pop and store this in variable `X`
# (X=1 for leap years; X=0 for non-leap years)
D # Duplicate the current month
2Qi # If it's equal to 2 (thus February):
\ # Discard the duplicated month
28X+ # Push 28 + isLeapYear from variable `X`
ë # Else:
< # Decrease the month by 1
7% # Modulo-7
É # Modulo-2
31α # Absolute difference with 31
} # Close the if-else statement
Step 2: Now we determine the current date, and loop an amount of times depending on the input:
že # Push the current day
žf # Push the current month
žg # Push the current year
) # Wrap all three into a list
I # Push the input-integer
Žª+ # Push compressed integer 42300
· # Double it to 84600 (60*60*24)
÷ # Integer-divide the input by 84600
Ä # Take its absolute value
F # And loop that many times:
Step 3: If the input was positive, calculate the next date:
© # Store the current date in variable `®` (without popping)
Idi # If the input is non-negative:
Y.V # Execute string `Y` as 05AB1E code to get the amount
# of days for the current month/year
‹i # If this is smaller than the current days:
® # Push the current date again
¬ # Get its first item (the days)
> # Increase the day by 1
0 # Push index 0
ë # Else:
® # Push the current date again
1 # Push day=1
¾ # Push index 0
ǝ # Insert days=1 at index 0 into the date
D # Duplicate it
Ås # Pop and push its middle item (the month)
D # Duplicate that month
12‹i # If it's smaller than 12:
> # Increase the month by 1
1 # Push index 1
ë # Else:
\ # Discard the duplicated month
1 # Push month=1
D # Push index 1
ǝ # Insert month=1 at index 1 into the date
¤ # Push its last item (the year)
> # Increase the year by 1
2 # Push index 2
} # Close the if-else statement
} # Close the if-else statement
ǝ # Insert the value at the given index into the date
Step 4: If the input was negative instead, calculate the previous date:
ë # Else (the input is negative):
ć # Extract head; push [month,year] and day separated
© # Store the day in variable `®` (without popping)
i # If day == 1:
ć # Extract head; push [year] and month separated
© # Store the month in variable `®` (without popping)
i # If month == 1:
< # Decrease the [year] by 1
D # Duplicate it
_ # Check if it's equal to 0 (1 if 0; 0 otherwise)
- # Subtract that (so we go from year 1 to -1)
12š31š # Prepend 12 and 31: [31,12,year-1-(year-1==0)]
ë # Else:
®<š # Prepend month-1 to the [year] list
D # Duplicate it
Y.V # Execute string `Y` as 05AB1E code to get the amount
# of days for this month/year
š # Prepend this to the [month-1,year] list
ë # Else:
®<š # Prepend day-1 to the [month,year] list
Step 5: After the loop, extract the year to output:
] # Close both the if-else and loop
θ # Pop the date, and only leave its last item (the year)
# (after which it is output implicitly as result)
See this 05AB1E tips of mine (section How to compress large integers?) to understand why Žª+
is 42300
.
new Date()
gives the date at my local time, but that might not be true in other languages. It depends on the language \$\endgroup\$sleep $n;date
being a valid bash answer? I notice there's no performance requirement :P \$\endgroup\$