Given a date (no time) in an ISO8601 format (e.g. 2022-10-01
), how could I reliably increment a given amount of days to it and get back the same ISO8601 format?
I tried the approach below but it fails due to time zones / daylight saving time:
function incrementDays(dateStr, daysToIncrement) {
const dateAtUTC = new Date(`${dateStr}T00:00:00.000Z`);
dateAtUTC.setDate(dateAtUTC.getDate() daysToIncrement);
return dateAtUTC.toISOString().slice(0, 10);
}
const tests = [{
dateStr: "2022-04-01",
daysToIncrement: 10,
expectedResult: "2022-04-11"
},
{
dateStr: "2022-10-01",
daysToIncrement: 1,
expectedResult: "2022-10-02" // This is failing with "2022-10-01"
},
{
dateStr: "2020-02-29",
daysToIncrement: 3,
expectedResult: "2020-03-03"
},
]
tests.forEach(({
dateStr,
daysToIncrement,
expectedResult
}) => {
const result = incrementDays(dateStr, daysToIncrement);
if (result === expectedResult) {
console.log("PASSED", `${dateStr} ${daysToIncrement} = ${result}`)
} else {
console.log("FAILED", `${dateStr} ${daysToIncrement} = ${result} (expected: ${expectedResult})`)
}
})
CodePudding user response:
use .setUTCDate
and .getUTCDate
instead
function incrementDays(dateStr, daysToIncrement) {
const dateAtUTC = new Date(`${dateStr}T00:00:00.000Z`);
dateAtUTC.setUTCDate(dateAtUTC.getUTCDate() daysToIncrement);
return dateAtUTC.toISOString().slice(0, 10);
}
const tests = [{
dateStr: "2022-04-01",
daysToIncrement: 10,
expectedResult: "2022-04-11"
},
{
dateStr: "2022-10-01",
daysToIncrement: 1,
expectedResult: "2022-10-02" // This is failing with "2022-10-01"
},
{
dateStr: "2020-02-29",
daysToIncrement: 3,
expectedResult: "2020-03-03"
},
]
tests.forEach(({
dateStr,
daysToIncrement,
expectedResult
}) => {
const result = incrementDays(dateStr, daysToIncrement);
if (result === expectedResult) {
console.log("PASSED", `${dateStr} ${daysToIncrement} = ${result}`)
} else {
console.log("FAILED", `${dateStr} ${daysToIncrement} = ${result} (expected: ${expectedResult})`)
}
})
CodePudding user response:
Consider adding the days while parsing the string, e.g.
function incrementDays(s, days = 0) {
let [y,m,d] = s.split(/\D/);
return new Date(Date.UTC(y, m-1, d days)).toISOString().slice(0,10);
}
// Add 3 days
console.log(incrementDays('2022-10-01', 3));
// Subtract 23 days
console.log(incrementDays('2022-10-01', -23));
// OP test
const tests = [{
dateStr: "2022-04-01",
daysToIncrement: 10,
expectedResult: "2022-04-11"
},
{
dateStr: "2022-10-01",
daysToIncrement: 1,
expectedResult: "2022-10-02" // This is failing with "2022-10-01"
},
{
dateStr: "2020-02-29",
daysToIncrement: 3,
expectedResult: "2020-03-03"
},
]
tests.forEach(({
dateStr,
daysToIncrement,
expectedResult
}) => {
const result = incrementDays(dateStr, daysToIncrement);
if (result === expectedResult) {
console.log("PASSED", `${dateStr} ${daysToIncrement} = ${result}`)
} else {
console.log("FAILED", `${dateStr} ${daysToIncrement} = ${result} (expected: ${expectedResult})`)
}
})