Working with moment.js

Moment.js is a javascript library that makes working with dates and times way easier than using native javascript methods. It’s worth its weight in gold.

That said, I’ve ran into some areas that haven’t been intuitive for me.

Manipulating moments

Let’s look at the following code:

1
2
3
var start = moment();
var startPlus1 = start.add('1', 'hours');
var startPlus3 = start.add('3', 'hours');

I expect the three values to be different. However, they are all the same and they all equal start + 4 hours.

Moment’s add method doesn’t return a new object. Rather it manipulates the given object. From another post, we can see that simply making a new variable isn’t a true separate copy of the object.

The workaround is quite simple. We can create a new moment from an old one.

1
2
var startPlus1 = moment(start).add('1', 'hours');
var startPlus3 = moment(start).add('3', 'hours');

Now are moments are all different and as expected.

Timezones

I was just about at peace thinking that I couldn’t work in any timezones other than local or UTC. And by “work”, I don’t mean simply displaying the time in the correct timezone. I mean, manipulating moments with functions like startOf and endOf.

As I write this it is 9:48am pacific time.

1
2
3
4
5
var start = moment().utcOffset(-5);
console.log(start.toDate());
// Output
Fri Aug 07 2015 09:48:15 GMT-0700 (PDT)

What I expected was Fri Aug 07 2015 09:48:15 GMT-0500 (CDT)
Another expectation was Fri Aug 07 2015 07:48:15 GMT-0700 (PDT)
I did not expect the current time. The utcOffset method appers to do nothing.

But what if we use moment’s formatting capabilites?

1
2
3
4
5
6
7
var start = moment('2015-08-05 10:00:00').utcOffset(-5);
console.log(start.toDate());
console.log(start.format('MM/DD/YYYY H:mm:ss'));
// Output
Wed Aug 05 2015 10:00:00 GMT-0700 (PDT)
08/05/2015 12:00:00

The times are different. 10am pacific it certainly not noon. The difference is that the formatted time has been backed off UTC by 5 hours… which is our CDT.

From this I conclude that Moment is storing the offset for use and not actually manipulating the underlying time. The good news is that it is getting used!

So now, if I wanted to find the start of a work day in central time, I can:

1
2
3
4
5
6
var time = moment('2015-08-05 10:00:00').utcOffset(-5);
var startOfWorkDay = moment(time).startOf('day').add(8, 'hours');
console.log(startOfWorkDay.toDate());
// Output
Wed Aug 05 2015 06:00:00 GMT-0700 (PDT)

The first line of output shows the correct time. 6am PDT would correlate to 8am CDT. Using the same principle to get an endOfWorkDay, I can now make comparisons to see if some arbitray time is during a work day in a given timezone.

The last piece is to be careful about how I get my offset. The timezone offsets are not consistent primarily due to daylight savings times. That’s a topic for another day.

avatar

Dev Blog