Converting JavaScript Date object to string


Problem

When building a JavaScript application we'll often want to get a string representing a date you can easily process. For example to save a date in a MySQL database. While it sounds simple, there's a fairly common mistake you'll find rather often and it's related to timezones.

Let's assume we've got a variable called inputDate. It's being managed by a date picker and when you inspect it, it will show you a rather long string representation like this Tue Jan 17 2017 00:00:00 GMT+0100 (W. Europe Standard Time). If you search on the internet, you'll find a ton of articles suggesting that you simply use this inputDate.toISOString().substr(0,10), but guess what happens? Our result looks like this 2017-01-16. It's one day off! Why?



Solution

When working with dates, no matter what language you're using, you have to pay a lot of attention to timezones, even when your application runs in just one zone. If you look at the string representation above, you can see that there's a time zone in it GMT+0100 (W. Europe Standard Time). Since our date picker has a time of 00:00:00, we are just selecting a date without a time, this will cause a problem. When using toISOString JavaScript will get rid of the timezone and correct our value by one hour which will be 11pm the day before.

If you just care about the day, you can easily create a new UTC date object with just the year, month and day:

var inputDate = new Date();
var utcDate =  new Date(Date.UTC(inputDate.getFullYear(), inputDate.getMonth(), inputDate.getDate()))
var dateString = utcDate.toISOString().slice(0, 10)

By using Date.UTC we get an object without a timezone which makes it possible to safely use toISOString.

Another approach which would even work with a time is to correct the date by the timezone offset:

var inputDate = new Date();
var dateOffset = (new Date(inputDate - (new Date()).getTimezoneOffset() * 60000))
var dateString = dateOffset.toISOString().slice(0, 10)

Please note that we don't remove the timezone with this approach, we simply include the offset which will then be removed by JavaScript when calling toISOString.

Comments




Please sign-in to post a comment