I am trying to write a function that will take a string like 07/2020
and then return whether it is more than three months away.
I have written a function isMoreThan3MonthsHence
that I am reasonably sure works correctly:
const isMoreThan3MonthsHence = ({ utcYear, utcMonth },
now = new Date,
target = new Date(Date.UTC(utcYear, utcMonth)),
threeMonthsAway = new Date(now.valueOf()).setUTCMonth(now.getUTCMonth() + 3)) =>
(target > threeMonthsAway)
console.log(isMoreThan3MonthsHence({ utcYear: 2020, utcMonth: 7 })) // true (correct!)
The problem comes when I try to construct a Date
object to use to populate the arguments for isMoreThan3MonthsHence
.
const validate = (str,
[localMonth, localYear] = str.split('/'),
date = new Date(+localYear, (+localMonth)-1)) =>
isMoreThan3MonthsHence({ utcYear: date.getUTCFullYear(), utcMonth: date.getUTCMonth() })
// Note: input is one-based months
console.log(validate('07/2020')) // false (but should be true!)
I think the reason is that new-ing up a Date
in validate
without specifying the timezone will use the local timezone in effect at the supplied date, which will be BST (UTC+1).
Wed Jul 01 2020 00:00:00 GMT+0100 (British Summer Time)
This time is actually 2300hrs on June 30th in UTC. So the month is actually 5
in zero-based terms. But I don't want this behavior. I want it so specifying July actually means July in UTC.
How can I fix this?