It's a little awkward, but this would do what you want:
=EDATE(INDEX($D$1:$O$2,1,MATCH($B$3,$D$2:$O$2,1)),1)
Breakdown:
You INDEX the entire range. Then you choose row 1 (where the dates are that you want to return).
The MATCH formula chooses the column. Match the value you want (B3) against the numeric range (D2:O2). The third variable determines whether you want 0 | Exact, -1 | Greater than or Equal To, or 1 | Less than or Equal To.
At first, you would think that you want -1. You can do this only if your data is sorted Z-A (December - January with your sample data). You also have to invert the row reference, so that 1 = bottom row, 2 = next row up, and so on.
Assuming that your data has to be in the order presented, we use EDATE to adjust for the difference. The INDEX(MATCH) finds the first value less than what you are looking for. EDATE adds one month to that, based on the logical progression of the data. Feel free to test with different values.
If you do invert your data, running December to January, the formula would look like this:
=INDEX($D$2:$O$3,2,MATCH($B$3,$D$4:$O$4,-1))
Bookmarks