Read my free-form date Given a date written in any (must handle all in the same program) of the following formats, parse it into a valid yyyy/mm/dd date.

17th May 2012
March 14th, 2016
20 February 2014
September 14, 2017
Sunday, June 8, 2015


Rules


Dates will sometimes be invalid, ie. incorrect day for the month or number of months in a year, you must handle both cases. Either by erroring out or returning a consistent falsey value, you choose. (They will however stick to the template formats above)
Padding for days and months less than 10 must be used to create a two digit output.
Month names will always be the full name, not shortened to their three character counterparts. 
You can assume the year will always be within the 0000-9999 range.
Negative numbers need not be handled.
You can create a full program or function so output can be in any format, printed to console or returned from a function. 
Input will always be a string, output must always be a string, if it makes it shorter to take it as a single argument in an array eg. ["17th May 2012"] you may do so and output can be the same ["2012/05/17"]
You can assume spelling in input will be correct.


BONUS: cos who here doesnt like a challenge ;)

If you can manage to also allow the input formats of The Fourteenth of March, 2016 or March the Fourteenth, 2016 you may take an extra 20 bytes off your code with any final byte counts less than 1 resulting in 1.

Here are the full written numbers for each of the days to avoid any confusion on spelling.

First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Nineth, Tenth, Eleventh, Twelfth, Thirteenth, Fourteenth, Fifteenth, Sixteenth, Seventeenth, Eighteenth, Nineteenth, Twentieth, Twenty First, Twenty Second, Twenty Third, Twenty Fourth, Twenty Fifth, Twenty Sixth, Twenty Seventh, Twenty Eighth, Twenty Nineth, Thirtieth, Thirty First


Test Cases

INPUT                           | Output
17th May 2012                   | 2012/05/17
March 14th, 2016                | 2016/03/14
20 February 2014                | 2014/02/20
September 14, 2017              | 2017/09/14
Sunday, June 8, 2015            | 2015/06/08
1st January 1918                | 1918/01/01

The Fourteenth of March, 2016   | 2016/03/14
March the Fourteenth, 2016      | 2016/03/14
November the Seventeenth, 2019  | 2019/11/17
The Thirtieth of April, 2016    | 2016/04/30

30 February 2014                | Invalid
September 99, 2017              | Invalid
Sunday, June8, 2015             | Invalid

The Thirty First of April, 2016 | Invalid
PowerShell, 91 89 91 56 bytes



date("$args"-replace'th|rd|st|(\b.*)day|,')-f yyyy/MM/dd


Try it online!

Takes input as a string. Uses a -replace to get rid of junk, then uses the built-in Get-Date command with the -format flag to specify the required yyyy/MM/dd format. That string is left on the pipeline and output is implicit.

Saved two bytes thanks to Mr Xcoder. Saved a huge chunk thanks to TessellatingHeckler's regex golfing.