Dates - JavaScript in Depth - Speaking JavaScript (2014)

Speaking JavaScript (2014)

Part III. JavaScript in Depth

Chapter 20. Dates

JavaScript’s Date constructor helps with parsing, managing, and displaying dates. This chapter describes how it works.

The date API uses the term UTC (Coordinated Universal Time). For most purposes, UTC is a synonym for GMT (Greenwich Mean Time) and roughly means the time zone of London, UK.

The Date Constructor

There are four ways of invoking the constructor of Date:

new Date(year, month, date?, hours?, minutes?, seconds?, milliseconds?)

Constructs a new date from the given data. The time is interpreted relative to the current time zone. Date.UTC() provides similar functionality, but relative to UTC. The parameters have the following ranges:

§ year: For 0 ≤ year ≤ 99, 1900 is added.

§ month: 0–11 (0 is January, 1 is February, etc.)

§ date: 1–31

§ hours: 0–23

§ minutes: 0–59

§ seconds: 0–59

§ milliseconds: 0–999

Here are some examples:

> new Date(2001, 1, 27, 14, 55)

Date {Tue Feb 27 2001 14:55:00 GMT+0100 (CET)}

> new Date(01, 1, 27, 14, 55)

Date {Wed Feb 27 1901 14:55:00 GMT+0100 (CET)}

As an aside, JavaScript has inherited the slightly weird convention of interpreting 0 as January, 1 as February, and so on, from Java.

new Date(dateTimeStr)

This is a date time string that is converted into a number, with which new Date(number) is invoked. Date Time Formats explains the date time formats. For example:

> new Date('2004-08-29')

Date {Sun Aug 29 2004 02:00:00 GMT+0200 (CEST)}

Illegal date time strings lead to NaN being passed to new Date(number).

new Date(timeValue)

Creates a date as specified in the number of milliseconds since 1 January 1970 00:00:00 UTC. For example:

> new Date(0)

Date {Thu Jan 01 1970 01:00:00 GMT+0100 (CET)}

The inverse of this constructor is the getTime() method, which returns the milliseconds:

> new Date(123).getTime()

123

You can use NaN as an argument, which produces a special instance of Date, an “invalid date”:

> var d = new Date(NaN);

> d.toString()

'Invalid Date'

> d.toJSON()

null

> d.getTime()

NaN

> d.getYear()

NaN

new Date()

Creates an object for the current date and time; it works the same as new Date(Date.now()).

Date Constructor Methods

The constructor Date has the following methods:

Date.now()

Returns the current date and time in milliseconds (since 1 January 1970, 00:00:00 UTC). It produces the same result as new Date().getTime().

Date.parse(dateTimeString)

Converts dateTimeString to milliseconds since 1 January 1970, 00:00:00 UTC. Date Time Formats explains the format of dateTimeString. The result can be used to invoke new Date(number). Here are some examples:

> Date.parse('1970-01-01')

0

> Date.parse('1970-01-02')

86400000

If it can’t parse a string, this method returns NaN:

> Date.parse('abc')

NaN

Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?)

Converts the given data to milliseconds since 1 January 1970 00:00:00 UTC. It differs from the Date constructor with the same arguments in two ways:

§ It returns a number, not a new date object.

§ It interprets the arguments as UTC, rather than as local time.

Date Prototype Methods

This section covers the methods of Date.prototype.

Time Unit Getters and Setters

Time unit getters and setters are available with the following signatures:

§ Local time:

§ Date.prototype.get«Unit»() returns Unit, according to local time.

§ Date.prototype.set«Unit»(number) sets Unit, according to local time.

§ Universal time:

§ Date.prototype.getUTC«Unit»() returns Unit, according to universal time.

§ Date.prototype.setUTC«Unit»(number) sets Unit, according to universal time.

Unit is one of the following words:

§ FullYear: Usually four digits

§ Month: Month (0–11)

§ Date: Day of the month (1–31)

§ Day (getter only): Day of the week (0–6); 0 is Sunday

§ Hours: Hour (0–23)

§ Minutes: Minutes (0–59)

§ Seconds: Seconds (0–59)

§ Milliseconds: Milliseconds (0–999)

For example:

> var d = new Date('1968-11-25');

Date {Mon Nov 25 1968 01:00:00 GMT+0100 (CET)}

> d.getDate()

25

> d.getDay()

1

Various Getters and Setters

The following methods enable you to get and set the time in milliseconds since 1 January 1970 and more:

§ Date.prototype.getTime() returns the milliseconds since 1 January 1970 00:00:00 UTC (see Time Values: Dates as Milliseconds Since 1970-01-01).

§ Date.prototype.setTime(timeValue) sets the date as specified in milliseconds since 1 January 1970 00:00:00 UTC (see Time Values: Dates as Milliseconds Since 1970-01-01).

§ Date.prototype.valueOf() is the same as getTime(). This method is called when a date is converted to a number.

§ Date.prototype.getTimezoneOffset() returns the difference between local time and UTC time in minutes.

The unit Year has been deprecated in favor of FullYear:

§ Date.prototype.getYear() is deprecated; use getFullYear() instead.

§ Date.prototype.setYear(number) is deprecated; use setFullYear() instead.

Convert a Date to a String

Note that conversion to a string is highly implementation-dependent. The following date is used to compute the output in the following examples (in Firefox, which had the most complete support when this book was written):

new Date(2001,9,30, 17,43,7, 856);

Time (human-readable)

§ Date.prototype.toTimeString():

17:43:07 GMT+0100 (CET)

The time, in the current time zone.

§ Date.prototype.toLocaleTimeString():

17:43:07

The time in a locale-specific format. This method is provided by the ECMAScript Internationalization API (see The ECMAScript Internationalization API) and does not make much sense without it.

Date (human-readable)

§ Date.prototype.toDateString():

Tue Oct 30 2001

The date.

§ Date.prototype.toLocaleDateString():

10/30/2001

The date, in a locale-specific format. This method is provided by the ECMAScript Internationalization API (see The ECMAScript Internationalization API) and does not make much sense without it.

Date and time (human-readable)

§ Date.prototype.toString():

Tue Oct 30 2001 17:43:07 GMT+0100 (CET)

Date and time, in the current time zone. For any Date instance that has no milliseconds (i.e., the second is full), the following expression is true:

Date.parse(d.toString()) === d.valueOf()

§ Date.prototype.toLocaleString():

Tue Oct 30 17:43:07 2001

Date and time in a locale-specific format. This method is provided by the ECMAScript Internationalization API (see The ECMAScript Internationalization API) and does not make much sense without it.

§ Date.prototype.toUTCString():

Tue, 30 Oct 2001 16:43:07 GMT

Date and time, in UTC.

§ Date.prototype.toGMTString():

Deprecated; use toUTCString() instead.

Date and time (machine-readable)

§ Date.prototype.toISOString():

2001-10-30T16:43:07.856Z

All internal properties show up in the returned string. The format is in accordance with Date Time Formats; the time zone is always Z.

§ Date.prototype.toJSON():

This method internally calls toISOString(). It is used by JSON.stringify() (see JSON.stringify(value, replacer?, space?)) to convert date objects to JSON strings.

Date Time Formats

This section describes formats for expressing points in time as strings. There are many ways of doing so: indicating just the date, including a time of day, omitting the time zone, specifying the time zone, and more. In its support for date time formats, ECMAScript 5 closely follows the standard ISO 8601 Extended Format. JavaScript engines implement the ECMAScript specification relatively completely, but there are still some variations, so you have to be vigilant.

The longest date time format is:

YYYY-MM-DDTHH:mm:ss.sssZ

Each part stands for several decimal digits of date time data. For example, YYYY means that the format starts with a four-digit year. The following subsections explain what each part means. Formats are relevant for the following methods:

§ Date.parse() can parse the formats.

§ new Date() can parse the formats.

§ Date.prototype.toISOString() creates a string in the aforementioned “full” format:

§ > new Date().toISOString()

'2014-09-12T23:05:07.414Z'

Date Formats (No Time)

The following date formats are available:

YYYY-MM-DD

YYYY-MM

YYYY

They include the following parts:

§ YYYY refers to year (Gregorian calendar).

§ MM refers to month, from 01 to 12.

§ DD refers to day, from 01 to 31.

For example:

> new Date('2001-02-22')

Date {Thu Feb 22 2001 01:00:00 GMT+0100 (CET)}

Time Formats (No Date)

The following time formats are available. As you can see, time zone information Z is optional:

THH:mm:ss.sss

THH:mm:ss.sssZ

THH:mm:ss

THH:mm:ssZ

THH:mm

THH:mmZ

They include the following parts:

§ T is the prefix of the time part of a format (a literal T, not a digit).

§ HH refers to hour, from 00 to 23. You can use 24 as a value for HH (which refers to hour 00 of the following day), but then all remaining parts must be 0.

§ mm indicates the minute, from 00 to 59.

§ ss indicates the second, from 00 to 59.

§ sss indicates the millisecond, from 000 to 999.

§ Z refers to time zone, either of the following two:

§ “Z” for UTC

§ “+” or “-” followed by a time “hh:mm”

Some JavaScript engines allow you to specify only a time (others require a date):

> new Date('T13:17')

Date {Thu Jan 01 1970 13:17:00 GMT+0100 (CET)}

Date Time Formats

Date formats and time formats can also be combined. In date time formats, you can use a date or a date and a time (or, in some engines, just the time). For example:

> new Date('2001-02-22T13:17')

Date {Thu Feb 22 2001 13:17:00 GMT+0100 (CET)}

Time Values: Dates as Milliseconds Since 1970-01-01

What the date API calls time is called a time value by the ECMAScript specification. It is a primitive number that encodes a date as milliseconds since 1 January 1970 00:00:00 UTC. Each date object stores its state as a time value, in the internal property [[PrimitiveValue]] (the same property that instances of the wrapper constructors Boolean, Number, and String use to store their wrapped primitive values).

WARNING

Leap seconds are ignored in time values.

The following methods work with time values:

§ new Date(timeValue) uses a time value to create a date.

§ Date.parse(dateTimeString) parses a string with a date time string and returns a time value.

§ Date.now() returns the current date time as a time value.

§ Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?) interprets the parameters relative to UTC and returns a time value.

§ Date.prototype.getTime() returns the time value stored in the receiver.

§ Date.prototype.setTime(timeValue) changes the date as specified via a time value.

§ Date.prototype.valueOf() returns the time value stored in the receiver. This method determines how dates are converted to primitives, as explained in the next subsection.

The range of JavaScript integers (53 bits plus a sign) is large enough that a time span can be represented that starts at approximately 285,616 years before 1970 and ends at approximately 285,616 years after 1970.

Here are a few examples of converting dates to time values:

> new Date('1970-01-01').getTime()

0

> new Date('1970-01-02').getTime()

86400000

> new Date('1960-01-02').getTime()

-315532800000

The Date constructor enables you to convert times values to dates:

> new Date(0)

Date {Thu Jan 01 1970 01:00:00 GMT+0100 (CET)}

> new Date(24 * 60 * 60 * 1000) // 1 day in ms

Date {Fri Jan 02 1970 01:00:00 GMT+0100 (CET)}

> new Date(-315532800000)

Date {Sat Jan 02 1960 01:00:00 GMT+0100 (CET)}

Converting a Date to a Number

A date is converted to a number via Date.prototype.valueOf(), which returns a time value. This allows you to compare dates:

> new Date('1980-05-21') > new Date('1980-05-20')

true

You can also perform arithmetic, but beware that leap seconds are ignored:

> new Date('1980-05-21') - new Date('1980-05-20')

86400000

WARNING

Using the plus operator (+) to add a date to another date or a number results in a string, because the default for the conversion to primitive is to convert dates to strings (consult The Plus Operator (+) for an explanation of how the plus operator works):

> new Date('2024-10-03') + 86400000

'Thu Oct 03 2024 02:00:00 GMT+0200 (CEST)86400000'

> new Date(Number(new Date('2024-10-03')) + 86400000)

Fri Oct 04 2024 02:00:00 GMT+0200 (CEST)