[Vuejs]-How to get years and months with momentjs and vuejs

3πŸ‘

βœ…

You can break the moment calculation down into milliseconds.

let fromTime = moment("2016-01-29").diff(moment(), "milliseconds")

Then create a duration object using the diff provided.

let duration = moment.duration(fromTime)

It will return a duration object that will have methods for milliseconds, seconds, minutes, hours, days, months and years.

The duration.methods() methods return negative values, thats why there is a divide by negative one / -1 to convert the values into positive ones.

Here is an example using the duration.years() and duration.months()

let timeString = duration.years() / -1 + " years and " + duration.months() / -1 + " months"

So as of right now the timeString would return 2 years and 6 months.

πŸ‘€jordanw

2πŸ‘

// import moment

var moment = require('moment')

// add this as a method in your component

 getYearsMonthsDays(date){
        let fromTime = moment(date).diff(moment(), "milliseconds")
        let duration = moment.duration(fromTime)
        let years = duration.years() / -1
        let months = duration.months() / -1
        let days = duration.days() / -1
        if (years > 0) {
            var Ys = years == 1? years + " year and ": years + " years and "
            var Ms = months == 1? months + " month": months + " months"
            return Ys + Ms
        } else {
            if (months > 0)
                return months == 1? months + " month": months + " months"
            else
                return days == 1? days + " day": days + " days"
        }
    }

// usage in component

{{ getYearsMonthsDays(date) }}

This works as expected with tweaks from @jordanw β€˜s response.
May be it could be made shorter or better but this works ok.

πŸ‘€nara_l

1πŸ‘

Here is a version that uses date-fns ans creates a custom filter

https://codesandbox.io/s/mmm0q9r61x

this is the code for the filter itself

import Vue from "vue";
import { differenceInMonths, differenceInYears } from "date-fns";

Vue.filter("tsDiff", (from, to) => {
  const tsTo = to || new Date();
  try {
    // return `${distanceInWords(from, tsTo)}`;
    let y = differenceInYears(from, tsTo);
    let m = differenceInMonths(from, tsTo) - y * 12;
    let r = [];
    if (y !== 0) {
      r.push(`${Math.abs(y)} Year${Math.abs(y) !== 1 ? "s" : ""}`);
    }
    if (m !== 0) {
      r.push(`${Math.abs(m)} Month${Math.abs(m) !== 1 ? "s" : ""}`);
    }
    r = r.join(" and ");
    if (y < 0 || m < 0) {
      r = r + " ago";
    } else {
      r = "In " + r;
    }
    return r;
  } catch (error) {
    // eslint-disable-next-line
    console.error(error);
    return "Invalid Date";
  }
});

once you import the filter (import './datefilter';), you can call from anywhere as {{ myDate | tsDiff }}

you can adjust the use as needed.

You can easily replace the use of differenceInYears and differenceInMonths with vanilla js so that you don’t need a dependency at all.

As a side note, have a look if you can replace momentjs with date-fns. Momentjs is a nice library, but you have to load the entire library no matter how much you are using. When you use Date-fns however, you can specify which parts you want to use, and only those get injected into the final build. This can save a lot on the final build size.

πŸ‘€Daniel

Leave a comment