Handling Dates in JavaScript
Tags: webdev, programming, javascript, beginners
Published: 2021-01-26 02:57:06

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**

Handling date and time are also important in many JavaScript programs. This is why JavaScript has a built-in `Date` object to handle manipulating dates. Dates objects contain a number that represents the milliseconds since January 1970 in UTC (the Linux epoch time).

We can do a lot of things with the Date object to manipulate dates. However, it has many quirks and missing functionality. Therefore, third-party libraries are better with handling dates than using the built-in Date object in many cases. Moment.js is one of the more popular ones, so it’s naturally it is the first choice when we need to manipulate dates in JavaScript.

Built in Date Object
====================

To work with dates in JavaScript, we have to create a `new Date` object. The constructor for the date object takes zero or more arguments. When there are no arguments passed in, then Date object created will have the current date and time in your local time zone, as of the time of instantiation.

The parameters it can accept include a date string, another date object, or the (years, month index, day, hour, minutes, seconds, and milliseconds) together. We can pass in a date string as follows to the date constructor:

```javascript
new Date('2019-01-01');
```

If we log the result, we get `‘Mon Dec 31 2018 16:00:00 GMT-0800 (Pacific Standard Time)’` since the date is stored in UTC and the browser is running on a computer in the Pacific Time Zone, which is 8 hours behind UTC at January 1, 2019 is when Pacific Standard Time.

As we can see, passing a date string to the `Date` constructor is confusing. Different browsers will parse date strings differently. Likewise, the `Date.parse` method also shouldn’t be used to parse date strings. We can see that date-only strings like the one we passed in are treated as UTC and not local time.

If we want to pass in a Date object to the constructor we can write:

```javascript
new Date(new Date());
```

We get something like ‘Sun Oct 20 2019 10:57:58 GMT-0700 (Pacific Daylight Time)’ when we log the result. This is shown in your local time.

We can pass in the year, month index, day, hour, minutes, seconds, and milliseconds into the constructor. Only year and month are required. So we can write something like:

```javascript
new Date(2019,0,1,0,0,0,0)
```

This will return ‘Tue Jan 01 2019 00:00:00 GMT-0800 (Pacific Standard Time)’ if we log it. Note that we have 0 in the second argument of the constructor. The second argument is the month index, which is 0 for January, 1 for February, and so on. So December would be 11. The rest of the arguments are what we expect. The first is the year, the third is the day, the fourth is hours, the fifth is minutes, 6th is seconds, and the last one is milliseconds.

We can convert a Date object to the UNIX timestamp, which is the number of milliseconds since January 1, 1970 UTC with the unary `+` operator, so if we write:

```javascript
+new Date(2019,0,1,0,0,0,0)
```

We get `1546329600000` when we log the output because it coerces the date to a number.

Another way to get the timestamp is by using the `.getTime()` method.

To alter the individual components of a Date object like setting the hours or day or getting components of a Date like the day of the week or day of the month, there are methods to do that in a Date object.

Methods in the Date Object
==========================

There are methods in the Date object to get and set parts of dates, and convert time to UTC, or set time zone offset. Some important Date object methods include the following:

Date.now()
----------

Returns the current time in the form of a UNIX timestamp with leap seconds ignored. This method is static.

Date.UTC()
----------

Returns the current time in the form of a UNIX timestamp with leap seconds ignored. This method is static. It accepts the same arguments as the longest list of arguments for the Date constructor which is year, month index, day, hour, minutes, seconds, and milliseconds, but only year and month are required. We can use it as in the following code:

```javascript
Date.UTC(2019,0,1,1,0,0,0)
```

Which we return something like `1546304400000`.

Getter Functions
================

Date.getDate()
--------------

Returns the day of the month according to local time. For example, if we have:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
console.log(date.getDate());
```

We would get 1 since we specified it as the day of the month in the constructor’s arguments.

Date.getDay()
-------------

Returns the day of the week (0–6) for the specified date according to local time, where 0 represents Sunday and 6 represents Saturday and 1 to 5 represents the days in between. For example, we can write:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
console.log(date.getDay());
```

Then we get 2, which is Tuesday.

Date.getFullYear()
------------------

Returns the 4 digit year of the specified date according to local time. For example, we can write:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
console.log(date.getFullYear());
```

Then we get 2019, which is the 4 digit year of `date`.

Date.getHours()
---------------

Return the hour (0–23) of the specified date according to local time. For example, we can write:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
console.log(date.getHours());
```

Then we get 0 which is what we specified in the hours argument in the constructor.

Date. getMilliseconds()
-----------------------

Returns the milliseconds of the specified date from 0 to 999 according to local time. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getMilliseconds());
```

This gets the milliseconds specified in the `date` object, which should return 0 as we specified in the constructor.

Date.getMinutes()
-----------------

Returns the minute (0–59) of the specified date in local time. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getMinutes());
```

Then we get 0 minutes as we specified in the constructor.

Date.getMonth()
---------------

Returns the month (From 0 for January to 11 for December) of the specified date according to local time. For example, we can write:

```
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getMonth());
```

Then we get month 0 for January as we specified in the constructor.

Date.getSeconds()
-----------------

Returns the seconds (0–59) in the specified date in local time. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getSeconds());
```

Then we get 0 seconds as we specified in the constructor.

Date.getTime()
--------------

Returns the UNIX timestamp for the specified date, which is the number of milliseconds since January 1, 1970 00:00:00 UTC. For prior times, it will be negative. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getTime());
```

Then we get 1546329600000 returned from the `getTime()` function. A shorthand for this is to use the unary `+` operator, like in the following code:

```
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(+date);
```

If we run the code above, we get the same result logged.

Date.getTimezoneOffset()
------------------------

Return time zone offset in minutes for the current location set on your host device. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getTimezoneOffset());
```

Then we get 480 if your host device is set to the Pacific Time Zone, since on January 1, 2019, the Pacific Time Zone is 8 hours behind UTC, so we get that the time zone offset is 480 minutes, which is 8 hours.

Date.getUTCDate()
-----------------

Returns the day of the month, from 1 to 31, in the specified date according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCDate());
```

We get 1 since we specified January 1, 2019 as the date.

Date.getUTCDay()
----------------

Return the day of the week from 0 to 6 according to the specified date in UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCDay());
```

Then we get 2 because January 1, 2019 is Tuesday.

Date.getUTCFullYear()
---------------------

Return the 4 digit year in the specified date according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCFullYear());
```

We get 2019 since this is what we specified in the date constructor.

Date.getUTCHours()
------------------

Return the hours from 0 to 23 in the specified date according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCHours());
```

If the locale setting is set to the Pacific Time Zone, we get 8 since we specified that the hour is 0 in local time which is the same as 8 in UTC on January 1, 2019.

Date.getUTCMilliseconds()
-------------------------

Returns the milliseconds of the specified date from 0 to 999 according to UTC. For example, we can write:

```
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCMilliseconds());
```

This gets the milliseconds specified in the `date` object, which should return 0 as we specified in the constructor.

Date.getUTCMonth()
------------------

Return the month from 0 for January to 11 for December in the specified time according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCMonth());
```

This gets the month specified in the `date` object, which should return 0 like we specified in the constructor.

Date.getUTCSeconds()
--------------------

Returns the seconds (0–59) in the specified date in UTC. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCSeconds());
```

Then we get 0 seconds as we specified in the constructor.

Date.getYear()
--------------

Returns the year, which is usually 2 to 3 digits in the specified date according to the local time zone.

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
console.log(date.getUTCSeconds());
```

Then we get 119 for 2019.

If we instead have:

```javascript
const date = new Date(1900, 0, 1, 0, 0, 0, 0);  
console.log(date.getYear());
```

We get 0 for 1900. And if we have:

```javascript
const date = new Date(2000, 0, 1, 0, 0, 0, 0);  
console.log(date.getYear());
```

Then we get 100 for 2000. So 1900 is year 0 according to the `getYear()` method. It’s much better to use the `getFullYear()` method instead of getting the correct year from a Date object.

Setter Functions
================

There are also corresponding setter functions for each of the getter functions we mentioned above. We have the following setter functions for the Date object:

Date.setDate()
--------------

Sets the day of the month according to local time. For example, if we have:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
date.setDate(2)  
console.log(date);
```

We would get ‘Wed Jan 02 2019 00:00:00 GMT-0800 (Pacific Standard Time)’ when the host device is set to the Pacific Time Zone since we specified 2 in the `setDate` function.

Date.setFullYear()
------------------

Sets the 4 digit year of the specified date according to local time. For example, we can write:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
date.setFullYear(2020)  
console.log(date.getFullYear());
```

Then we get 2020, which is the 4 digit year of `date`.

Date.setHours()
---------------

Sets the hour (0–23) of the specified date according to local time. For example, we can write:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
date.setHours(3)  
console.log(date.getHours());
```

Then we get 3 when we call `getHours` which is what we specified in the hours argument in the `setHours` function.

Date. setMilliseconds()
-----------------------

Sets the milliseconds of the specified date from 0 to 999 according to local time. For example, we can write:

```javascript
const date = new Date(2019,0,1,0,0,0,0);  
date.setMilliseconds(3)  
console.log(date.getMilliseconds());
```

This sets the milliseconds specified in the `date` object, which should return 3 as we specified in the `setMilliseconds` function when we call the `getMilliseconds` function.

Date.setMinutes()
-----------------

Sets the minute (0–59) of the specified date in local time. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setMinutes(20)  
console.log(date.getMinutes());
```

Then we get 20 minutes returned from `getMinutes()` like we specified in the `setMinutes` function.

Date.setMonth()
---------------

Sets the month (From 0 for January to 11 for December) of the specified date according to local time. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setMonth(3)  
console.log(date.getMonth());
```

Then we get month 3 returned from `getMonth()` after we set it by `setMonth()`

Date.setSeconds()
-----------------

Sets the seconds (0–59) in the specified date in local time. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setSeconds(10);  
console.log(date.getSeconds());
```

Then we get 10 seconds from `getSeconds()` like we specified in the `setSeconds` function.

Date.setTime()
--------------

Sets the UNIX timestamp for the specified date, which is the number of milliseconds since January 1, 1970 00:00:00 UTC. For prior times, it will be negative. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setTime(100)  
console.log(date.getTime());
```

Then we get 100 returned from the `getTime()` function since we set it to 100 with `setTime` .

Date.setUTCDate()
-----------------

Sets the day of the month, from 1 to 31, in the specified date according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setUTCDate(2)  
console.log(date.getUTCDate(2));
```

We get 2 since we specified 2 in `setUTCDate`

Date.setUTCFullYear()
---------------------

Sets the 4 digit year in the specified date according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setUTCFullYear(2020)  
console.log(date.getUTCFullYear());
```

We get 2020 with `getUTCFullYear()` since this is what we specified in the date `setUTCFullYear()` function.

Date.setUTCHours()
------------------

Sets the hours from 0 to 23 in the specified date according to UTC. For example, if we write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setUTCHours(2)  
console.log(date.getUTCHours());
```

We get 2 with `getUTCHours()` since we specified it when we call `setUTCHours()`.

Date.setUTCMilliseconds()
-------------------------

Sets the milliseconds of the specified date from 0 to 999 according to UTC. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setUTCMilliseconds(10)  
console.log(date.getUTCMilliseconds());
```

This gets the milliseconds with `getUTCMilliseconds()`, which should return 10 as we specified in the `setUTCMilliseconds()`.

Date.setUTCMonth()
------------------

Return the month from 0 for January to 11 for December in the specified time according to UTC. For example, if we write:

```
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setUTCMonth(3);  
console.log(date.getUTCMonth());
```

This gets the month specified in the `date` object, which should return 3 from `getUTCMonth()` like we specified in the `setUTCMonth()` call.

Date.setUTCSeconds()
--------------------

Sets the seconds (0–59) in the specified date in UTC. For example, we can write:

```javascript
const date = new Date(2019, 0, 1, 0, 0, 0, 0);  
date.setUTCSeconds(10);  
console.log(date.getUTCSeconds());
```

Then we get 10 seconds when we called `getUTCSeconds()` since we specified in 10 when we called `setUTCSeconds()`.

The `setYear()` method set the ye. It’s much better to use the `setFullYear()` method instead for getting the correct year from a Date object.

The Date object has a few limitations. For example, it doesn’t support time zones. This creates problems when we need time zones data in our dates. JavaScript dates only supports the local time zone, UTC, or time zone offsets relative to UTC. Only some of the conversions between these time zones are allowed when manipulating date objects. For example, when we convert Date objects to a date string, we can only choose between local time and UTC. The JavaScript Date object stores dates in UTC internally.

Moment.js
=========

Manipulating time and date in JavaScript is painful because of the limitations that we discussed above. Even with the functions available with `Date` objects, there are plenty of chances for bugs and errors. Also, there are no functions for formatting times and dates which is a big problem. To solve this, we use moment.js. This is the best library available for dealing with time.

The native JavaScript Date objects have issues with time zones with YYYY-MM-DD dates being parsed into UTC time as opposed to local time. This creates bugs for developers who aren’t aware of this problem. See [https://stackoverflow.com/questions/29174810/javascript-date-timezone-issue](https://stackoverflow.com/questions/29174810/javascript-date-timezone-issue)

Also there are differences in support for parts of Dates in different browsers. (See [https://stackoverflow.com/questions/11253351/javascript-date-object-issue-in-safari-and-ie](https://stackoverflow.com/questions/11253351/javascript-date-object-issue-in-safari-and-ie))

It is also hard to add and subtract timestamps with the built-in Date functions. There is no way to do this without writing a lot of code and doing a lot of checks. Also, there is no way to compare 2 times.

Formatting dates is also not available without writing your own code for using third party libraries.

Moment.js solves all of these issues by providing built-in functions to do all these common operations. It provides functions for parsing and formatting dates.

The `moment` constructor is where you can pass in a date string, and a `moment` object will be created. For example, you can pass in:

```javascript
moment('2019-08-04')
```

You will get back a `moment` which you can compare with other `moment` objects, and add or subtract by different time spans.

If you do not pass in anything to the `moment` constructor, you get the current date and time.

It also takes a second argument. If you want to make sure a date is parsed as a YYYY-MM-DD date, then write `moment(‘2019–08–04’, 'YYYY-MM-DD')`. If you don’t know the format of your date or time, then you can pass in an array of possible formats and Moment will pick the right one:

```javascript
moment('2019–08–04', ['YYYY-MM-DD', 'DD-MM-YYYY']);
```

After you create a Moment object, then you can do many things like formatting dates:

```javascript
const a = moment('2019–08–04', 'YYYY-MM-DD').format('MMMM Do YYYY, h:mm:ss a');  
console.log(a);// August 4th 2019, 12:00:00 am

const b = moment('2019–08–04', 'YYYY-MM-DD').format('dddd');  
console.log(b);// Sunday

const c = moment('2019–08–04', 'YYYY-MM-DD').format("MMM Do YY");  
console.log(c);// Aug 4th 19

const d = moment('2019–08–04', 'YYYY-MM-DD').format('YYYY [escaped] YYYY');      
console.log(d);// 2019 escaped 2019

const e = moment('2019–08–04', 'YYYY-MM-DD').format();  
console.log(e);// 2019-08-04T00:00:00-07:00
```

From the above examples, we see that we can format dates in pretty much any way we want.

We can also tell what time span a date is relative to another date by writing:

```javascript
const augDate = moment('2019–08–04', 'YYYY-MM-DD');  
const sepDate = moment('2019–09–04', 'YYYY-MM-DD');  
console.log(augDate.from(sepDate)); // a month ago
```

We can also add or subtract Moment dates:

```javascript
const augDate = moment('2019–08–04', 'YYYY-MM-DD');  
const sepDate = moment('2019–09–04', 'YYYY-MM-DD');  
console.log(augDate.add(10, 'days').calendar()); // 08/14/2019  
console.log(augDate.subtract(10, 'days').calendar()); // 07/25/2019
```

It is easy to compare 2 dates:

```javascript
moment('2010-01-01').isSame('2010-01-01', 'month'); // true  
moment('2010-01-01').isSame('2010-05-01', 'day');   // false, different month  
moment('2008-01-01').isSame('2011-01-01', 'month'); // false, different year
```

You can also check if a date has Daylight Saving Time in effect or not:

```javascript
const augDate = moment('2019–08–04', 'YYYY-MM-DD');  
const decDate = moment('2019–12–04', 'YYYY-MM-DD');  
console.log(augDate.isDST()) // true  
console.log(decDate.isDST()) // false
```

And you can convert back to JavaScript date any time by calling the `toDate()` function on a Moment object.

As we can see, JavaScript’s Date object has limited capabilities when it comes to manipulating dates. It also doesn’t parse dates very well and has no ability for formatting dates easily. This is why we need to use libraries like Moment.js to fill in the gaps so we can create bug-free code that manipulates dates much more easily.