You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JavaScript has a built-in object `Date` which stores date and time, and provides methods for their management.
4
4
5
+
<!-- prettier-ignore -->
6
+
~~~exercism/caution
7
+
It was based on Java's `java.util.Date` class, which was replaced in the early 2010s, but for backwards compatibility, JavaScript's `Date` sticks around.
8
+
9
+
Because of how hard it is to work with Dates in general and because of how bad or non-existing timezone handling is, many libraries exist such as `moment.js`, `day.js`, `date-fns` and `luxon`.
10
+
None of these are available on Exercism.
11
+
12
+
In your own projects, do not use a deprecated / unmaintained package such as `moment.js` but rely on more modern alternatives like `luxon`, or the not yet widely available [Temporal][mdn-temporal].
13
+
This exercise focusses on `Date`, which will remain relevant until the end of JavaScript.
A `Date` object in an instance of the `Date` class. It can be created without passing any arguments to the constructor function. This results in a `Date` object that represents the current date and time:
20
+
A `Date` object in an instance of the `Date` class.
21
+
It can be created without passing any arguments to the constructor function.
22
+
This results in a `Date` object that represents the current date and time:
// Shows current day, date and time in your time zone.
27
+
// Shows current day, date and time (in your time zone).
14
28
```
15
29
16
-
However, different types of arguments can also be used to create date object, as follows:
30
+
### Unix timestamp (number)
17
31
18
-
### Timestamp value
32
+
If a number is passed in, this will be interpreted as a `timestamp`.
33
+
A timestamp is an integer number representing the number of **milliseconds** that has passed since **1 January 1970 [UTC][defn-utc]+0**.
19
34
20
-
> A timestamp is an integer number representing the number of **milliseconds** that has passed since **Jan 1st of 1970 [UTC][utc-defn]+0**, however, _with reference to your local time zone._
21
-
> This can be used as an argument for the Date object.
22
-
>
23
-
> ```javascript
24
-
>constJan01_1970=newDate(0);
25
-
>// 0 means 01.01.1970 UTC+0
26
-
>
27
-
>constJan02_1970=newDate(24*3600*1000);
28
-
>// adding 24 hours, we get 02.01.1970 UTC+0
29
-
>
30
-
>// Note that the objects created here would show the corresponding time in your time zone.
31
-
>```
32
-
>
33
-
> [^1]
35
+
```javascript
36
+
constepoch=newDate(0);
37
+
// Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)
34
38
35
-
### Timestamp string
39
+
constanother=newDate(1749508766627);
40
+
// Tue Jun 10 2025 00:39:26 GMT+0200 (Central European Summer Time)
41
+
```
42
+
43
+
One may expect `new Date(0)` to generate the "earliest" date object, but JavaScript will convert the date to your local timezone, which means that only those around [GMT / with an UTC+0][defn-gmt] timezone will actually get the [Unix epoch][defn-unix-epoch] value.
44
+
45
+
### ISO 8601 timestamp (string)
36
46
37
47
You can pass a string value representing a date to the `Date` constructor.
38
-
The string needs to follow a format that is recognized by the `Date.parse()` method.
39
-
You will learn more about this below.
48
+
The **only** format that is consistent across implementations is the [simplified version][mdn-date-string-format] of the internationally recognized and standardized so-called [ISO 8601 timestamp strings][defn-iso8601].
49
+
50
+
A moment in time at [UTC][defn-gmt] looks like this:
If the timestamp does not end in `Z`, and it does not end with `+HH:MM` or `-HH:MM`, indicating a timezone offset, because of historical reasons, the following applies:
83
+
84
+
> When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
85
+
> The interpretation as a UTC time is due to a historical spec error that was not consistent with ISO 8601 but could not be changed due to web compatibility.
86
+
> See [Broken Parser – A Web Reality Issue][ref-broken-parser].
40
87
41
88
### Date object
42
89
43
-
An existing date object can also be used as an argument.
90
+
An existing date object can also be used as a constructor argument.
44
91
This makes a copy of the existing `Date` object with the same date and time.
45
92
46
93
```javascript
47
94
constt1=newDate();
48
95
constt2=newDate(t1);
49
-
50
96
// Values of t1 and t2 will be the same.
51
97
```
52
98
53
-
### Individual date and time component values
54
-
55
-
> Given at least a year and month, this form of `Date()` returns a `Date` object whose component values _(year, month, day, hour, minute, second, and millisecond)_ all come from the following parameters.
56
-
> Any missing fields are given the lowest possible value (1 for day and 0 for every other component).
57
-
> The parameter values are all evaluated against the _local time zone, rather than UTC_.
58
-
>
59
-
> -`year`: Integer values from 0 to 99 map to the years 1900 to 1999.
60
-
> All other values are the actual year.
61
-
> -`monthIndex`: Integer value representing the month, beginning with _0 for January to 11 for December_.
62
-
> If a value greater than 11 is passed in, then those months will be added to the date.
63
-
> For example, new Date(1990, 12, 1) will return January 1st, 1991.
64
-
> -`day` (Optional): Integer value representing the day of the month.
65
-
> The default is 1.
66
-
> -`hours` (Optional): Integer value between 0 and 23 representing the hour of the day.
67
-
> Defaults to 0.
68
-
> -`minutes` (Optional): Integer value representing the minute segment of a time.
69
-
> The default is 0 minutes past the hour.
70
-
> -`seconds` (Optional): Integer value representing the second segment of a time.
71
-
> The default is 0 seconds past the minute.
72
-
> -`milliseconds` (Optional): Integer value representing the millisecond segment of a time.
73
-
> The default is 0 milliseconds past the second.
74
-
>
75
-
> [^2]
99
+
### Supplying individual date and time component values
100
+
101
+
A date representing a date can be created by passing three numbers.
102
+
A date representing a date and time can be created by passing in 6 numbers.
// Creates Date for Jan 5 2014 13:24 if your local timezone is equivalent to UTC.
83
110
```
84
111
85
-
## `Date.parse()`
86
-
87
-
`Date.parse()` takes **string as a input and returns a timestamp** (number of milliseconds from 1 Jan 1970 UTC+0), provided the string is in the format YYYY-MM-DDTHH:mm:ss.sssZ, where:
88
-
89
-
> -`YYYY-MM-DD` - is the date: year-month-day.
90
-
> -`T` - The character "T" is used as the delimiter
91
-
> -`HH:mm:ss.sss` - is the time: hours, minutes, seconds and milliseconds.
92
-
> -`Z` - This _optional_ part denotes the time zone.
93
-
> If `Z` is present, the `Date` will be set to UTC.
94
-
> If `Z` is not present, it will be Local Time.
95
-
>
96
-
> If the format is invalid, `NaN` is returned. [^3]
112
+
The second value is the `month`, which starts at `0` for January, up to `11` for December.
97
113
98
-
Shorter variants are also possible, like `YYYY-MM-DD` or `YYYY-MM` or even `YYYY`. However, note that these variants **set the `Date` to UTC**, even though `Z` not mentioned.
99
-
To understand what exactly happens check out [this section][mdn-diff-assumed-timezone] of a MDN page.
114
+
## `Date.parse()`
100
115
101
-
<!-- prettier-ignore-start -->
102
-
~~~~exercism/caution
103
-
The use of `Date.parse()` (and the timestamp string method which works similarly) is strongly discouraged due to browser differences and inconsistencies. [^4]
104
-
~~~~
105
-
<!-- prettier-ignore-end -->
116
+
You may find mentions of or references to a date parsing function `Date.parse`.
117
+
Because there are only a few invariants (truths) for this function and because the rest of the implementation is not specified (and thus not standard), one should not use it.
106
118
107
119
## Accessing `Date` components
108
120
109
-
The following are the methods to access the year, month and so on from the Date object:
110
-
111
-
> -`getFullYear()`- Get the year (4 digits)
112
-
> -`getMonth()`- Get the month, from 0 to 11.
113
-
> -`getDate()`- Get the day of month, from 1 to 31.
114
-
> -`getHours()`, `getMinutes()`, `getSeconds()`, `getMilliseconds()`- Get the corresponding time components.
115
-
> -`getDay()`- Get the day of week, from 0 (Sunday) to 6 (Saturday).
116
-
> -`getTime()`- Get the number of milliseconds passed since 01.01.1970 UTC.
117
-
>
118
-
> [^5]
121
+
There are various methods on date objects that return the components of the date:
119
122
120
123
```javascript
121
-
constdate0=newDate(0); //Jan 1 1970 00:00:00
122
-
let month =date0.getMonth()); // => 0; as Jan is the month
123
-
let date =date0.getDay(); // Find out which day the new year of 1970 was!
124
-
125
-
constdate1=newDate(2020, 11, 13, 5); // Dec 13 2020 5:00:00
126
-
let millsecs =date1.getTime(); // find out how many have milliseconds passed since Jan 1 1890!
124
+
getFullYear(); // Get the year (4 digits)
125
+
getMonth(); // Get the month, from 0 to 11.
126
+
getDate(); // Get the day of month, from 1 to 31.
127
+
getHours(); // Get the hour in a 24 clock, from 0 to 23
128
+
getMinutes(); // Get the minutes, from 0 to 59
129
+
getSeconds(); // Get the seconds, from 0 to 59
130
+
getMilliseconds(); // Get the milliseconds, from 0 and 999
131
+
getDay(); // Get the day of week, from 0 (Sunday) to 6 (Saturday).
127
132
```
128
133
129
-
## Modifying `Date` components
130
-
131
-
The following methods allow to modify date/time components :
132
-
133
-
> -`setFullYear(year, [month], [date])`
134
-
> -`setMonth(month, [date])`
135
-
> -`setDate(date)`
136
-
> -`setHours(hour, [min], [sec], [ms])`
137
-
> -`setMinutes(min, [sec], [ms])`
138
-
> -`setSeconds(sec, [ms])`
139
-
> -`setMilliseconds(ms)`
140
-
> -`setTime(timestamp)` (sets the whole date by milliseconds since 01.01.1970 UTC)
141
-
>
142
-
> Parameters in `[]` above are _optional_.
143
-
> If not mentioned, the components are not modified.
144
-
> Every one of them except `setTime()` has a UTC-variant, for instance: `setUTCHours()`. [^6]
134
+
Each of these has an applicable `set` variant (e.g. `setFullYear`) to update the value.
135
+
Any overflowing value rolls over to the next component:
145
136
146
137
```javascript
147
-
let today =newDate();
148
-
149
-
today.setHours(0); // still today, but only the hour is changed to 0
150
-
151
-
today.setHours(0, 0, 0, 0); // still today, now sharply 00:00:00
152
-
```
138
+
constdate=newDate('2025-02-28T12:42:00Z');
139
+
// => Fri Feb 28 2025 13:42:00 GMT+0100 (Central European Standard Time)
153
140
154
-
## Calculating Time Difference and `Date.now()`
141
+
date.setDate(29);
142
+
// there was no February 29th in 2025.
155
143
156
-
To measure the time elapsed between two given dates, we can use the `Date.getTime()` method.
144
+
date.getDate();
145
+
// => 1
157
146
158
-
```javascript
159
-
constd1=newDate(2021, 12, 11, 5, 13, 32, 21);
160
-
constd2=newDate(2021, 12, 23, 4, 12, 55);
161
-
162
-
let timeElapsed =d2.getTime() -d1.getTime(); // => 1033162979
147
+
date.toString();
148
+
// => Sat Mar 01 2025 13:42:00 GMT+0100 (Central European Standard Time)
163
149
```
164
150
165
-
Moreover, if we wish to measure the time taken on a live basis, for example the time taken for execution for program, we could use `Date.now()` which provides the timestamp of current time.
166
-
167
-
## Comparing Dates
168
-
169
-
We can use `<` and `>` operators to compare two `Date` objects, the date occuring _later being treated as greater_.
151
+
There are UTC variants for all the methods that disregard the local timezone.
170
152
171
-
The `==` or `===` do not work with `Date`, and output `false` in any case, even if dates are equal.
172
-
However, we could use the `Date.getTime()` method to obtain the timestamps (which is of the data type `number`) and compare them using equality operators.
153
+
## Converting from date
173
154
174
-
```javascript
175
-
constd1=newDate(2021, 12, 11);
176
-
constd2=newDate(1990, 11, 23);
155
+
Date objects have a method `getTime()` that returns the UNIX timestamp in milliseconds, ie. amount of milliseconds the midnight at the beginning of January 1, 1970, UTC.
156
+
Additionally, a method `toISOString()` is available to convert from a date object to a ISO 8601 timestamp string.
177
157
178
-
d1 > d2; // true
179
-
180
-
constd1Copy=newDate(d1); // d1Copy will be same as d1
181
-
182
-
d1Copy === d1; // false, even though they are same
Greater than (`>`) and greater than or equals (`>=`) as well as less than (`<`) and less than or equals (`<=`) can be used directly between two dates or a date and a number.
161
+
This works because JavaScript will try to coerce the date to a primitive.
When doing a comparison between two dates or date and a number, JavaScript calls [`[Symbol.toPrimitive]("number")`][mdn-to-primitive] which internally calls [`date.valueOf()`][mdn-date-value-of].
166
+
The latter is the same as calling [`date.getTime()`][mdn-date-get-time].
0 commit comments