2020 is a leap year, so there's a February 29th:
>> make date! [29 2 2020] == 29-Feb-2020
But let's say you have a year like 2017, in which there is no February 29th. R3-Alpha and Red are smart enough not to let you MAKE such bad dates, or to load them as literals. e.g. Red:
>> make date! [28 2 2017] == 28-Feb-2017 >> make date! [29 2 2017] *** Script Error: cannot MAKE/TO date! from: [29 2 2017] >> 29-Feb-2017 *** Script Error: cannot MAKE/TO date! from: [day month year]
But let's say you aren't making it directly, but mutating a date. For instance to try to set a February 2017 date's day to the 29th anyway. In R3-Alpha and Red:
>> date: 28-Feb-2017 == 28-Feb-2017 >> date/day: 29 == 29 >> date == 1-Mar-2017
It gets weirder than that.
>> date: 28-Feb-2017 == 28-Feb-2017 >> date/day: 1000 == 1000 >> date == 28-Oct-2019 >> date/day: -1000 == -1000 >> date == 3-Jan-2017
It's doing some kind of off-kilter date math when you assign them. Note that setting the date to 1000 effectively pushed into the future only by the overflow (assumed your 28 was intentional, and everything beyond that wasn't). But then going back -1000 made no such assumptions; so you didn't get back where you started.
Where the odd behavior is coming from is a reuse of the normalization code for date math. Basically, if you start from a valid date and add days / months / years / seconds, you need to reconcile after the math.
But setting date fields item-wise is not date math. I propose it be held to the same rules as MAKE or LOAD of a DATE!.