A moment with Moment.js

Jason Arnold
5 min readSep 6, 2017

--

https://unsplash.com/search/photos/time?photo=BXOXnQ26B7o

One of the trickier things to deal with in JavaScript is formatting of dates. If you are wanting a human-readable calculation of a timestamp or you are doing something with date math then you may have to jump through quite a few hoops to get the output you want.

The Date() Object

Dates in JavaScript all start with creating a new instance of the ‘Date’ object.

new Date()

By default this returns an object that contains the information for the current date and time

If you are looking through server logs or are programmatically generating output that contains timestamps then you can also pass those to the Date object. These are usually in the form of Unix Epoch Time which is the number of seconds since January 1st 1970 at midnight.

Hmmm. At the time of this writing the Unix Epoch Time is 1504725855 so you might have expected the return value to be something closer to the current date. This is because Date() expects a value you pass to it to be in milliseconds. So after a quick multiplication, you get this.

Date Formatting

What happens when you want to format that date a bit or only want part of it? Let’s say you only want the date from the above output. The time and timezone don’t matter to you. How do you get it?

The Date() object has several methods you can call on it to get just parts of the output. These include methods like .getDay(), .getMonth(), .getDate(), and .getFullYear(). But these have their own shortcomings.

Here is a bit of JavaScript where the timestamp is being hardcoded and passed to a new instance of Date(). Then some of the contents of the Date object are being held in variables and then consoled out.

var timestamp = 1504721767;
var timestampDate = new Date(timestamp * 1000);
var day = timestampDate.getDay();
var month = timestampDate.getMonth();
var date = timestampDate.getDate();
var year = timestampDate.getFullYear();
//target output is 'Wed Sep 06 2017'
console.log(`${day} ${month} ${date} ${year}`)
//actual output is
3 8 6 2017

Hmmm. Not quite what you were after? This is because the values in the Date() object for things like the day and month are in integers starting from 0 rather than words like ‘Wed’ and ‘Sep’. If that is the output you want, then you will could use a couple of Javascript switches to get there.

var timestamp = 1504721767;
var timestampDate = new Date(timestamp * 1000);
var day = timestampDate.getDay();
var month = timestampDate.getMonth();
var date = timestampDate.getDate();
var year = timestampDate.getFullYear();
switch(day) {
case 0:
day = 'Sun';
break;
case 1:
day = 'Mon';
break;
case 2:
day = 'Tue';
break;
case 3:
day = 'Wed';
break;
case 4:
day = 'Thu';
break;
case 5:
day = 'Fri';
break;
case 6:
day = 'Sat';
break;
case 7:
day = 'Sun';
break;
}
switch(month) {
case 0:
month = 'Jan';
break;
case 1:
month = 'Feb';
break;
case 2:
month = 'Mar';
break;
case 3:
month = 'Apr';
break;
case 4:
month = 'May';
break;
case 5:
month = 'Jun';
break;
case 6:
month = 'Jul';
break;
case 7:
month = 'Aug';
break;
case 8:
month = 'Sep';
break;
case 9:
month = 'Oct';
break;
case 10:
month = 'Nov';
break;
case 11:
month = 'Dec';
break;
}
//target output is 'Wed Sep 06 2017'
console.log(`${day} ${month} ${date} ${year}`)
//actual output is
Wed Sep 6 2017

Closer… Now you just need to deal with the lack of a leading 0 on a date that is less than 10. A quick if/else statement and you should have it.

var timestamp = 1504721767;
var timestampDate = new Date(timestamp * 1000);
var day = timestampDate.getDay();
var month = timestampDate.getMonth();
var date = timestampDate.getDate();
var year = timestampDate.getFullYear();
switch(day) {
case 0:
day = 'Sun';
break;
case 1:
day = 'Mon';
break;
case 2:
day = 'Tue';
break;
case 3:
day = 'Wed';
break;
case 4:
day = 'Thu';
break;
case 5:
day = 'Fri';
break;
case 6:
day = 'Sat';
break;
case 7:
day = 'Sun';
break;
}
switch(month) {
case 0:
month = 'Jan';
break;
case 1:
month = 'Feb';
break;
case 2:
month = 'Mar';
break;
case 3:
month = 'Apr';
break;
case 4:
month = 'May';
break;
case 5:
month = 'Jun';
break;
case 6:
month = 'Jul';
break;
case 7:
month = 'Aug';
break;
case 8:
month = 'Sep';
break;
case 9:
month = 'Oct';
break;
case 10:
month = 'Nov';
break;
case 11:
month = 'Dec';
break;
}
if(date < 10) {
date = '0' + date.toString();
}
//target output is 'Wed Sep 06 2017'
console.log(`${day} ${month} ${date} ${year}`)
//actual output is
Wed Sep 06 2017

Wow, that’s a LOT of code for what seems like a pretty simple ask. There’s a lot that could go wrong here and if you ever wanted a different output you’d have to rewrite or discard most of this. If only there was a better way…

Moment.js

Moment.js is a JavaScript library that is made just for handing dates. It works both in the browser or in Node.js.

The new Date() equivalent in Moment.js is .moment() and it is an object containing the data for the current time (if no value is passed to it). You then pass this object the .format() method and you get to see the data in the object.

You can also pass a timestamp to .moment() and you will get information on that specific date and time.

One of the best things about Moment.js is just how easy it is to display data from it and how many options you have when doing so. To get the same date value we got from the last example all we have to pass to .format() is a few characters and we get the same output. Here we are passing the same timestamp to the .moment() method and then passing the desired arguments in a string to .format().

A lot less hassle here. No messing with switches or logic to deal with formatting. Pretty straight forward and to the point. Moment.js is pretty easy to set up and use and may save you a bit of effort when dealing with date and time formatting.

I hope this post was useful to you. If so, please send me a clap (or whatever they are when you read this) or leave a comment below. Thanks for reading!

--

--