Legalize Reversed Date Input:

A Date (containing dd, MM and yyyy). A date-object, or three separate integers are also valid as input.

Output:

Each part (dd, MM and yyyy) individually reverted and than rounded to the nearest valid date.

For example (in the format dd-MM-yyyy):
21-10-2016 becomes 12-01-6102

Challenge rules:


Only dd, MM, yyyy is valid, but the order and which separate-symbols you use is your own choice.
So these are some valid format examples: dd-MM-yyyy; MM/dd/yyyy; yyyy MM dd; ddMMyyyy, etc.
And these are some invalid format examples: dd MMM yyyy; dd-MM-'yy; etc.
You can also choose to just input a Date-object if your language supports it or three separate integer parameters, instead of the string representing a date.
Please state which date-format you've used! (And the input and output must be in the same format.) It is also allowed to output a Date-object, as long as it can handle all test cases and the challenge rule below.
The Julian to Gregorian Calendar transition is ignored for this challenge. So 1582 is just a valid reversed year for 2851.
See Challenge info / tips for all valid years, months and days.
Since you cannot have February as reversed of any other month, you don't have to worry about leap years.


All reversed years, months and days:


The year can always be reversed without a problem, reaching from 0001 (reversed of 1000) to 9999 (remains 9999). (So 0000 isn't a valid input, and there are also no test cases for it.)
The only months you'll have reversed are: January (reversed from October / 10); October (reversed from January / 01); November (remains November / 11); and December (reversed from every other month / 02-09, 12).
The only days you'll have reversed are: 01 (reversed from 10), 02 (reversed from 20), 03 (reversed from 30), 10 (reversed from 01), 11 (remains 11), 12 (reversed from 21), 13 (reversed from 31), 20 (reversed from 02), 21 (reversed from 12), 22 (remains 22), 30 (reversed from 03 or the same as 31 for November!), 31 (reversed from 04-09 / 13-19 / 23-29).


General rules:


This is code-golf, so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return statements/output, full programs. Your call.
Default Loopholes are forbidden.
If possible, please add a link with a test for your code.
Also, please add an explanation if necessary.


Test cases (dd-MM-yyyy as format):

21-07-2016   -&gt;   12-12-6102
12-11-1991   -&gt;   21-11-1991
01-01-2000   -&gt;   10-10-0002
27-08-1875   -&gt;   31-12-5781
18-12-2010   -&gt;   31-12-0102
13-01-1981   -&gt;   31-10-1891
04-11-1671   -&gt;   30-11-1761  // Semi-tricky case, since November has 30 days
28-11-2036   -&gt;   30-11-6302  // Semi-tricky case, since November has 30 days
14-06-1855   -&gt;   31-12-5581
30-10-9999   -&gt;   03-01-9999
01-01-2851   -&gt;   10-10-1582
CJam, 24 bytes

qS/Wf%[_1=:=31^sCs].e&lt;S*


I/O format is dd mm yyyy.

Try it online!

Same byte count, I/O format mm dd yyyy:

qS/Wf%_0=:=1231^s2/.e&lt;S*


Try it online!

Explanation

qS/     e# Read input, split around spaces.
Wf%     e# Reverse each component.
[       e# Set marker for new list.
  _1=   e#   Duplicate reversed strings, extract reversed month.
  :=    e#   Check for equality of the characters. This gives 1 for
        e#   November (11) and 0 for everything else.
  31^   e#   XOR the result with 31, giving 30 for November and 31
        e#   for everything else.
  s     e#   Convert the result to a string, "30"/"31".
  Cs    e#   Push 12, convert to string, "12".
]       e# Wrap "30"/"31" and "12" in a list.
.e&lt;     e# Element-wise minimum. This clamps the day and month to their
        e# respective maxima.
S*      e# Join the result with spaces.


The other version works similarly, except that we start from the integer 1230 or 1231 before converting it to ["12" "30"]  or ["12" "31"].