Skip to content
FLAVIO COPES
flaviocopes.com
2026

The definitive guide to JavaScript Dates

By

Learn how to work with dates in JavaScript using the Date object, from creating instances with new Date() to milliseconds since 1970 and UNIX timestamps.

~~~

JavaScript’s Date object represents one moment in time as milliseconds since January 1, 1970, UTC.

You can use it to create timestamps, read or change date parts, compare moments, and format dates for a locale.

Working with dates can be complicated. Time zones and daylight saving time make apparently simple operations tricky.

Three social media posts from developers complaining about JavaScript date handling being difficult and frustrating

JavaScript offers date handling through the built-in Date object.

The Date object

A Date object instance represents a single point in time.

Despite being named Date, it also handles time.

It does not store a time zone. Local getter and formatting methods interpret the timestamp using the runtime’s current time zone.

Initialize the Date object

We initialize a Date object by using

new Date()

This creates a Date object pointing to the current moment in time.

Internally, dates are expressed in milliseconds since January 1, 1970 at 00:00:00 UTC.

You might be familiar with the UNIX timestamp: that represents the number of seconds that passed since that famous date.

Important: Unix timestamps are commonly expressed in seconds. JavaScript timestamps use milliseconds.

If we have a UNIX timestamp, we can instantiate a JavaScript Date object by using

const timestamp = 1530826365
new Date(timestamp * 1000)

If the timestamp already uses milliseconds, don’t multiply it.

Make sure you pass a number:

new Date(Number(timestamp) * 1000)

If we pass 0 we’d get a Date object that represents the time at Jan 1st 1970 (UTC):

new Date(0)

You can pass a string in JavaScript’s standard date-time format:

new Date('2018-07-22T07:22:13Z')
new Date('2018-07-22T07:22:13+02:00')

Z means UTC. The second example includes an explicit offset from UTC.

Avoid formats such as 07/22/2018 or July 22, 2018 in data exchanged between systems. Parsing non-standard strings is implementation-dependent and can differ between browsers.

One detail can surprise you:

new Date('2018-07-22') // midnight UTC
new Date('2018-07-22T07:22:13') // local time

A date-only standard string is interpreted as UTC. A date and time without an offset is interpreted as local time.

Date.parse() accepts the same string format and returns a timestamp in milliseconds:

Date.parse('2018-07-22T07:22:13Z')

Read the MDN Date.parse() reference before parsing external input.

You can also pass a set of ordered values that represent each part of a date: the year, the month (starting from 0), the day, the hour, the minutes, seconds and milliseconds:

new Date(2018, 6, 22, 7, 22, 13, 0)
new Date(2018, 6, 22)

When you pass two or more numeric parameters, JavaScript uses them as local date parts. Omitted parts use defaults:

new Date(2018, 6) //Sun Jul 01 2018 00:00:00 GMT+0200 (Central European Summer Time)

Months start at 0, so month 6 is July. Days start at 1.

The numeric component form uses the local time zone. Two computers in different time zones can therefore create different timestamps from the same components.

So, summarizing, you can create a new Date object in 4 ways

Timezones

Include Z or a numeric offset in a standard date-time string when the moment must be unambiguous:

new Date('2018-07-22T07:22:13Z')
new Date('2018-07-22T07:22:13+07:00')

Don’t rely on abbreviations such as CET or EST. They are not part of the standard date-time string format and can be ambiguous.

Date conversions and formatting

Given a Date object, there are lots of methods that will generate a string from that date:

const date = new Date('2018-07-22T07:22:13+02:00')

date.toString() // local date and time
date.toTimeString() // local time
date.toUTCString() //"Sun, 22 Jul 2018 05:22:13 GMT"
date.toDateString() // local date
date.toISOString() //"2018-07-22T05:22:13.000Z" (ISO 8601 format)
date.toLocaleString() // localized date and time
date.toLocaleTimeString() // localized time
date.getTime() //1532236933000

Locale-formatted output depends on the runtime’s locale and time zone. Don’t compare it to a hardcoded string.

The Date object getter methods

A Date object offers several methods to check its value. These depend on the current time zone of the computer.

On a computer using UTC+2, this example returns:

const date = new Date('2018-07-22T07:22:13+02:00')

date.getDate() //22
date.getDay() //0 (0 means sunday, 1 means monday..)
date.getFullYear() //2018
date.getMonth() //6 (starts from 0)
date.getHours() //7
date.getMinutes() //22
date.getSeconds() //13
date.getMilliseconds() //0 (not specified)
date.getTime() //1532236933000
date.getTimezoneOffset() //-120 (the difference from UTC, in minutes)

There are equivalent UTC versions of these methods, that return the UTC value rather than the values adapted to your current timezone:

date.getUTCDate() //22
date.getUTCDay() //0 (0 means sunday, 1 means monday..)
date.getUTCFullYear() //2018
date.getUTCMonth() //6 (starts from 0)
date.getUTCHours() //5 (not 7 like above)
date.getUTCMinutes() //22
date.getUTCSeconds() //13
date.getUTCMilliseconds() //0 (not specified)

Editing a date

A Date object offers several methods to edit a date value:

const date = new Date(2018, 6, 22, 7, 22, 13)

date.setDate(newValue)
date.setFullYear(newValue) //note: avoid setYear(), it's deprecated
date.setMonth(newValue)
date.setHours(newValue)
date.setMinutes(newValue)
date.setSeconds(newValue)
date.setMilliseconds(newValue)
date.setTime(newValue)

setMonth() uses zero-based months, so March is month 2. setDate() uses the day of the month, starting at 1.

Example:

const date = new Date(2018, 6, 22, 7, 22, 13)

date.setDate(23)
date.toString() //local time on July 23, 2018 at 07:22:13

Fun fact: those methods “overlap”, so if you, for example, set date.setHours(48), it will increment the day as well.

Good to know: you can add more than one parameter to setHours() to also set minutes, seconds and milliseconds: setHours(0, 0, 0, 0) - the same applies to setMinutes and setSeconds.

Most local setter methods also have a UTC equivalent:

const date = new Date('2018-07-22T05:22:13Z')

date.setUTCDate(newValue)
date.setUTCFullYear(newValue)
date.setUTCMonth(newValue)
date.setUTCHours(newValue)
date.setUTCMinutes(newValue)
date.setUTCSeconds(newValue)
date.setUTCMilliseconds(newValue)

Get the current timestamp

If you want to get the current timestamp in milliseconds, you can use the shorthand

Date.now()

instead of

new Date().getTime()

Date values overflow into adjacent units

Pay attention. If you overflow a month with the days count, there will be no error, and the date will go to the next month:

new Date(2018, 6, 40) //local time on August 9, 2018

The same goes for months, hours, minutes, seconds and milliseconds.

Format dates according to the locale

The Internationalization API formats dates for a locale and time zone.

It’s exposed by the Intl object, which also helps localizing numbers, strings and currencies.

We’re interested in Intl.DateTimeFormat().

Here’s how to use it.

Format a date according to the computer default locale:

const date = new Date(2018, 6, 22, 7, 22, 13)
new Intl.DateTimeFormat().format(date) //"22/07/2018" in my locale

Format a date according to a different locale:

new Intl.DateTimeFormat('en-US').format(date) //"7/22/2018"

Intl.DateTimeFormat method takes an optional parameter that lets you customize the output. To also display hours, minutes and seconds:

const options = {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
}

new Intl.DateTimeFormat('en-US', options).format(date) //"7/22/2018, 7:22:13 AM"
new Intl.DateTimeFormat('it-IT', options).format(date) //"22/7/2018, 07:22:13"

You can also try different options and locales in my free date formatting tool, which generates the code for you.

Compare two dates

You can calculate the difference between two dates using Date.getTime():

const date1 = new Date('2018-07-10T07:22:13Z')
const date2 = new Date('2018-07-22T07:22:13Z')
const diff = date2.getTime() - date1.getTime() //difference in milliseconds

In the same way you can check if two dates are equal:

const date1 = new Date('2018-07-10T07:22:13Z')
const date2 = new Date('2018-07-10T07:22:13Z')
if (date2.getTime() === date1.getTime()) {
  //dates are equal
}

Keep in mind that getTime() compares exact moments, including the time.

If you only care about calendar dates, decide which time zone defines that date before resetting or comparing the time. Midnight in one time zone can be the previous day in another.

~~~

Related posts about js: