9
Given three non-negative integers y
, m
, and d
(of which at least one must be positive) and a valid date with a positive year (in any reasonable format that includes the year, month, and day, and no additional information), output the date that is y
years, m
months, and d
days after the original date.
The Gregorian calendar is to be used for all dates (even dates prior to the adoption of the Gregorian calendar).
The method for computing the next date is as follows:
- Add
y
to the year - Add
m
to the month - Normalize the date by applying rollovers (e.g.
2018-13-01
->2019-01-01
) - If the day is past the last day of the month, change it to the last day in the month (e.g.
2018-02-30
->2018-02-28
) - Add
d
to the day - Normalize the date by applying rollovers (e.g.
2019-01-32
->2019-02-01
)
Leap years (years divisible by 4, but not divisible by 100 unless also divisible by 400) must be handled appropriately. All inputs and outputs will be within the representable integer range of your language.
Test Cases
Test cases are provided in the format input => output
, where input
is a JSON object.
{"date":"2018-01-01","add":{"d":1}} => 2018-01-02
{"date":"2018-01-01","add":{"M":1}} => 2018-02-01
{"date":"2018-01-01","add":{"Y":1}} => 2019-01-01
{"date":"2018-01-30","add":{"M":1}} => 2018-02-28
{"date":"2018-01-30","add":{"M":2}} => 2018-03-30
{"date":"2000-02-29","add":{"Y":1}} => 2001-02-28
{"date":"2000-02-29","add":{"Y":4}} => 2004-02-29
{"date":"2000-01-30","add":{"d":2}} => 2000-02-01
{"date":"2018-01-01","add":{"Y":2,"M":3,"d":4}} => 2020-04-05
{"date":"2018-01-01","add":{"Y":5,"M":15,"d":40}} => 2024-05-11
You may use this JSFiddle for testing.
This is code-golf, so the shortest solution (in each language) wins.
Sandbox post (deleted) – Mego – 2018-07-20T22:21:37.450
2@LuisfelipeDejesusMunoz The input format is not important, as is the norm here on PPCG. – Mego – 2018-07-20T23:05:25.907
Is there any restriction to the upper bounds of
y
,m
andd
(e.g. couldd
be 2147483000?) – ErikF – 2018-07-21T03:44:10.003@ErikF
All inputs and outputs will be within the representable integer range of your language.
– Mego – 2018-07-21T04:00:22.7401What about output formats? Can we output a date object? Can we take a date object? – Asone Tuhid – 2018-07-21T09:00:26.693
Uh, excuse me, but I think step 3 makes step 4 obsolete. Do the "rollovers" in step 3 start from the month and not the day? Or are they only applied once, so that, for example,
2007-01-28
withd=33
becomes2007-01-61
→2007-02-30
? – Erik the Outgolfer – 2018-07-21T12:19:57.200Is it OK if I output e.g.
Sat Mar 3 00:00:00 UTC 2018
? – wastl – 2018-07-21T15:20:15.133@wastl Yeah that's fine, since that's the default representation of a date as a datetime stream. – Mego – 2018-07-21T15:39:22.583
@EriktheOutgolfer The rollovers in step 3 are for the month, since you can't properly determine what the last day of the month is until you've normalized the month. You don't rollover the day of the month in step 4 - you just set it to the maximum of the calculated day and the last day of the month. – Mego – 2018-07-21T15:41:20.920