vue中Momentjs计算两个时间差值表现为人类可读格式(转)

原文链接:http://www.idouxs.cn/?p=926

我们知道momentjs是一个很强大的时间计算工具,用起来真的很方便。

我在一次项目开发的时候要求通过选择一个日期,来计算这个人的年龄:格式为xx岁xx个月xx天,即人类可读格式。

我们知道moment有个diff算法,但是这个不满足我的需求,它虽然能获取两个时间之间差值时长,但是用起来不是很方便,贴下它用法吧:

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

然后,在经过我继续翻找文档的时候发现了一款插件:precise-range

我们可以直接npm安装:

npm install moment-precise-range-plugin

也可以把文件下载下来,他只是一个js文件,代码其实没多少,我贴一下:

if (typeof moment === "undefined" && typeof require === "function") {
  var moment = require("moment");
}

(function(moment) {
  var STRINGS = {
    nodiff: "",
    year: "year",
    years: "岁",
    month: "month",
    months: "个月",
    day: "day",
    days: "天",
    hour: "hour",
    hours: "hours",
    minute: "minute",
    minutes: "minutes",
    second: "second",
    seconds: "seconds",
    delimiter: " "
  };

  function pluralize(num, word) {
    return num + " " + STRINGS[word + (num === 1 ? "" : "s")];
  }

  function buildStringFromValues(
    yDiff,
    mDiff,
    dDiff,
    hourDiff,
    minDiff,
    secDiff
  ) {
    var result = [];

    if (yDiff) {
      result.push(pluralize(yDiff, "year"));
    }
    if (mDiff) {
      result.push(pluralize(mDiff, "month"));
    }
    if (dDiff) {
      result.push(pluralize(dDiff, "day"));
    }
    if (hourDiff) {
      result.push(pluralize(hourDiff, "hour"));
    }
    if (minDiff) {
      result.push(pluralize(minDiff, "minute"));
    }
    if (secDiff) {
      result.push(pluralize(secDiff, "second"));
    }

    return result.join(STRINGS.delimiter);
  }

  function buildValueObject(
    yDiff,
    mDiff,
    dDiff,
    hourDiff,
    minDiff,
    secDiff,
    firstDateWasLater
  ) {
    return {
      years: yDiff,
      months: mDiff,
      days: dDiff,
      hours: hourDiff,
      minutes: minDiff,
      seconds: secDiff,
      firstDateWasLater: firstDateWasLater
    };
  }
  moment.fn.preciseDiff = function(d2, returnValueObject) {
    return moment.preciseDiff(this, d2, returnValueObject);
  };

  moment.preciseDiff = function(d1, d2, returnValueObject) {
    var m1 = moment(d1),
      m2 = moment(d2),
      firstDateWasLater;

    m1.add(m2.utcOffset() - m1.utcOffset(), "minutes"); // shift timezone of m1 to m2

    if (m1.isSame(m2)) {
      if (returnValueObject) {
        return buildValueObject(0, 0, 0, 0, 0, 0, false);
      } else {
        return STRINGS.nodiff;
      }
    }
    if (m1.isAfter(m2)) {
      var tmp = m1;
      m1 = m2;
      m2 = tmp;
      firstDateWasLater = true;
    } else {
      firstDateWasLater = false;
    }

    var yDiff = m2.year() - m1.year();
    var mDiff = m2.month() - m1.month();
    var dDiff = m2.date() - m1.date();
    var hourDiff = m2.hour() - m1.hour();
    var minDiff = m2.minute() - m1.minute();
    var secDiff = m2.second() - m1.second();

    if (secDiff < 0) {
      secDiff = 60 + secDiff;
      minDiff--;
    }
    if (minDiff < 0) {
      minDiff = 60 + minDiff;
      hourDiff--;
    }
    if (hourDiff < 0) {
      hourDiff = 24 + hourDiff;
      dDiff--;
    }
    if (dDiff < 0) {
      var daysInLastFullMonth = moment(
        m2.year() + "-" + (m2.month() + 1),
        "YYYY-MM"
      )
        .subtract(1, "M")
        .daysInMonth();
      if (daysInLastFullMonth < m1.date()) {
        // 31/01 -> 2/03
        dDiff = daysInLastFullMonth + dDiff + (m1.date() - daysInLastFullMonth);
      } else {
        dDiff = daysInLastFullMonth + dDiff;
      }
      mDiff--;
    }
    if (mDiff < 0) {
      mDiff = 12 + mDiff;
      yDiff--;
    }

    if (returnValueObject) {
      return buildValueObject(
        yDiff,
        mDiff,
        dDiff,
        hourDiff,
        minDiff,
        secDiff,
        firstDateWasLater
      );
    } else {
      return buildStringFromValues(
        yDiff,
        mDiff,
        dDiff
        // hourDiff,
        // minDiff,
        // secDiff
      );
    }
  };
})(moment);

这里我把源码做了下小改动,只是输出的日期单位改了改,问题不大,大家用的时候自行下载哈。

然后说下使用方法

main.js中引入插件:我是下的js文件

require("@/utils/moment-precise-range.js"); //加载moment插件

然后我又在utils.js中封装了一个方法:

/**
   *
   * @param {String} startTime "2019-01-10"
   * @param {String} endTime 时间戳10位
   */
  computedTime(startTime = "", endTime) {
    let st = startTime == "" ? moment().format("YYYY-MM-DD") : startTime;
    let s_d = moment(this.formatDate(endTime), "YYYY-MM-DD");
    let e_d = moment(st, "YYYY-MM-DD");
    return moment
      .preciseDiff(s_d, e_d)
      .replace("year", "岁")
      .replace("month", "个月")
      .replace("day", "天");
  },

当我们想知道某个人的年龄时,可以这样算:

let age = computedTime("",birthday );

当然,我还用它来获取合同临期,试用期临期等一些时间段值。

好了,写的不是很好,有问题或者您有更好的方法请给博主留言,欢迎哦~

更多前端知识请浏览前端园地其它文章^_^!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值