Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I work around mutability in moment.js?

People also ask

What should I use instead of MomentJS?

There are several libraries out there that can potentially replace Moment in your app. The creators of Moment recommend looking into Luxon, Day. js, date-fns, js-Joda, or even replacing Moment with native JS.

Why you shouldnt use MomentJS?

However, Moment. js has too many drawbacks compared to modern date and time libraries. Its API is not immutable, it is large and it doesn't support tree shaking. Even the Moment team discourages to use their library in new projects.

Is JavaScript moment immutable?

The moment object in Moment. js is mutable. This means that operations like add, subtract, or set change the original moment object.

Is MomentJS still used?

Conclusion. MomentJS isn't completely gone yet. But on their website they suggest you look beyond Moment unless you fall into specific usecases. Luxon seems to be the biggest replacement for Moment that is futureproof for now.


There's a Moment.js plugin on NPM called frozen-moment - You could use moment().freeze() in place of Object.freeze(moment()).

Otherwise, vanilla Moment.js has a clone method that should help you avoid mutability problems, so you could do something like this:

var a = moment(),
    b = a.clone(); // or moment(a)

UPDATE:

It has been two years since I wrote this answer. In this time, another library for working with dates has surfaced and gained a lot of traction: https://date-fns.org/

This library is immutable by default and follows a modular, functional architecture, which means it is better suited to tree shaking and client-side bundling. If you are working on a project that makes extensive use of Webpack on the client side, and find that Moment.js is giving you trouble with your build, or even if Moment.js' mutability is causing you a lot of headache, then you should give date-fns a try.


It's an old question and apologies for shameless self promotion as this is not my intention, just hope it will help someone.

In addition to what razorbeard says (.clone() etc) I created NPM module that attaches immutable methods to whatever Moment.js comes with out of the box. The intention is not to break existing code so module adds new methods with Immu appended to its name.

Each instance returned by moment factory will be decorated with immutable methods e.g moment().startOf() will have corresponding startOfImmu(), add() will have addImmu() etc. Each of those returns new moment rather then modifying existing one. To use it just pass moment factory to momentImmutableMethods to get access to new immutable methods. Example:

var moment = require('moment'); // or moment-timezone 
import { momentImmutableMethods } from 'moment-immutable-methods';

// to decorate instances with immutable methods we need to extend moment factory as below:
momentImmutableMethods(moment);

// now every instance returned by moment will have Immu methods attached.


// IMMUTABLE EXAMPLE
// we using immutable methods that were attached to every instance, these have Immu appended to original name
const ddd = moment({
  hour: 5,
  minute: 10
});
// Moment {_isAMomentObject: true, _i: {…}, _isUTC: false, _pf: {…}, _locale: Locale, …}
const eee = ddd.startOfImmu('day');
// Moment {_isAMomentObject: true, _i: {…}, _isUTC: false, _pf: {…}, _locale: Locale, …}
console.log(ddd === eee);
// false
const fff = eee.startOfImmu('month');
// Moment {_isAMomentObject: true, _i: {…}, _isUTC: false, _pf: {…}, _locale: Locale, …}
console.log(ddd === fff);
// false
console.log(eee === fff);
// false
console.log(ddd.format('DD/MM/YY HH:mma'));
// "14/04/18 05:10am"
console.log(eee.format('DD/MM/YY HH:mma'));
// "14/04/18 00:00am"
console.log(fff.format('DD/MM/YY HH:mma'));
// "08/04/18 00:00am"

Its on NPM at https://www.npmjs.com/package/moment-immutable-methods