Posted:
Recently, I ran into an issue with time zones and date strings. I was running an Express app and the toDate
sanitizer from validator.js via express validator.
Just for illustrative purposes, let’s say I want to delete the oldest users that fall within a specific date range by making a request like this.
axios.delete('/users', {
startDate: '2020-06-01',
endDate: '2020-09-01'
})
My route definition could look like this.
app.delete('/users',
body('startDate').toDate(),
body('endDate').toDate(),
(req, res) => {
const startDate = req.body.startDate
const endDate = req.body.endDate
// Delete all users where their created_at
// is between startDate and endDate
}
)
Then, I can expect startDate
and endDate
to be instances of the Date object. If you console log them you should see this.
startDate 2020-06-01T00:00:00.000Z
endDate 2020-08-01T00:00:00.000Z
Since there was no time portion in the request, the Date object interpreted it as midnight UTC. If there were any users that have a created_at
column of 05/31/2020 at 9:00pm Eastern, they would be incorrectly deleted. The reason is because their created_at
timestamp would be stored in the database as 2020-06-01T01:00:00.000Z
UTC.
One solution to this problem would be to pass the timezone in the request like this.
axios.delete('/users', {
startDate: '2020-06-01',
endDate: '2020-09-01',
timezone: 'America/New_York'
})
Then, to remove the toDate
sanitizers.
app.delete('/users',
(req, res) => {
// ...
}
)
You can manually parse the dates using a library like Luxon.
import { DateTime } from 'luxon'
app.delete('/users', (req, res) => {
const timezone = req.body.timezone
const startDate = DateTime.fromFormat(req.body.startDate, 'yyyy-MM-dd', { zone: timezone })
.startOf('day')
.toUTC()
.toJSDate()
const endDate = DateTime.fromFormat(req.body.endDate, 'yyyy-MM-dd', { zone: timezone })
.startOf('day')
.toUTC()
.toJSDate()
// ...
})
Now if you console log the start and end date, you should get the correct times.
startDate 2020-06-01T04:00:00.000Z
endDate 2020-08-01T04:00:00.000Z