moment.js - 测试日期是否为今天、昨天、一周内或两周前

53

我正在使用moment.js尝试确定一个日期是今天、昨天、一周前还是更早之前(两周前或更久)。

对于前两种情况,我已经完成了:

var today = moment().startOf('day');
var yesterday = moment().subtract(1, 'days').startOf('day');

if (moment(localTime).isSame(today, 'd')) // today
    // do something
if (moment(localTime).isSame(yesterday, 'd')) // yesterday
    // do something

这是正确的吗?

但是,如何检查一个日期是否是一周前或更早(例如,两周前)?


1
"1周前"是什么意思?是指前天之前,但在上个星期五之后(因为今天是星期五)吗? - acdcjunior
你只是在寻找isBeforeisAfter函数吗?还是需要其他的东西? - Matt Johnson-Pint
@acdcjunior,你说得对,确实应该是7天前。 - William Poussier
6个回答

108

这是一个可能有用的东西:

var REFERENCE = moment("2015-06-05"); // fixed just for testing, use moment();
var TODAY = REFERENCE.clone().startOf('day');
var YESTERDAY = REFERENCE.clone().subtract(1, 'days').startOf('day');
var A_WEEK_OLD = REFERENCE.clone().subtract(7, 'days').startOf('day');

function isToday(momentDate) {
    return momentDate.isSame(TODAY, 'd');
}
function isYesterday(momentDate) {
    return momentDate.isSame(YESTERDAY, 'd');
}
function isWithinAWeek(momentDate) {
    return momentDate.isAfter(A_WEEK_OLD);
}
function isTwoWeeksOrMore(momentDate) {
    return !isWithinAWeek(momentDate);
}

console.log("is it today? ..................Should be true: "+isToday(moment("2015-06-05")));
console.log("is it yesterday? ..............Should be true: "+isYesterday(moment("2015-06-04")));
console.log("is it within a week? ..........Should be true: "+isWithinAWeek(moment("2015-06-03")));
console.log("is it within a week? ..........Should be false: "+isWithinAWeek(moment("2015-05-29")));
console.log("is it two weeks older or more? Should be false: "+isTwoWeeksOrMore(moment("2015-05-30")));
console.log("is it two weeks older or more? Should be true: "+isTwoWeeksOrMore(moment("2015-05-29")));

查看一个包含更多测试的JSFiddle演示,以便根据需要进行微调。


非常好。我自己也在尝试实现它,离你的解决方案并不远,只是我忘记了 clone(),因此得到了奇怪的结果。 - William Poussier
7
是的,这是因为moment()对象是可变的。如果你调用someDate.subtract(),它实际上会改变someDate的值。在许多语言中,日期对象是不可变的,因此 moment.js 的可变性确实会产生奇怪的结果。 - acdcjunior
我认为除了A_WEEK_OLD之外,startOf()并不是必要的。 - Jonah
@Jonah 注意,REFERENCE 只是用于测试的固定值,在实际情况中可能是任何值。 - acdcjunior
@acdcjunior 我知道,但isSame并不关心它正在比较的是一天的开始。 - Jonah
请记得对于包含时间部分的日期使用 isSame(date, "day") - Nina Satragno

30

更精确的答案如下

var today = moment();
var yesterday = moment().subtract(1, 'day');

var engagementDate = (Date to be compare);

if(moment(engagementDate).isSame(today, 'day'))
  console.log('Today');
else if(moment(engagementDate).isSame(yesterday, 'day'))
  console.log('Yesterday');

完美的解决方案。谢谢@Gurpinder - Ibad Shaikh

7

今天最简单的解决方案:

const result = moment(date).isSame(moment(), "day")

昨天的最简解决方案:

const result = moment(date).isSame(moment().subtract(1, 'day'), "day")

4

diff 函数可能对您的情况有所帮助,并且通常用于检查自某个日期以来的确切天数。

var sampleDaysAgo = moment().subtract(28, 'days'); //28 just for test
var today = moment();

console.log(today.diff(sampleDaysAgo, 'days')); // 28 

示例


0

从2.14版本开始,您可以自定义calendar()函数

moment().calendar(YOUR_DATE, {
  sameDay: function (now) {
    if (this.isBefore(now)) {
      return '[Will Happen Today]';
    } else {
      return '[Happened Today]';
    }
    /* ... */
  }
});

这是为“日历”类型的事件设计的。

http://momentjs.com/docs/#/displaying/calendar-time/


-1

Moment已经包含了一些这种逻辑

您可能想查看他们的源代码,了解humanize代码 https://github.com/moment/moment/blob/ed1fc742b179708d0a987a639979178616309f93/src/lib/duration/humanize.js

以及fromNow逻辑

https://github.com/moment/moment/blob/497f918515ae6ab900f008f19523b1e4ae5e2450/src/lib/moment/from.js

我发现这很有用,可以看看他们是如何做的。

字符串格式化的方式取决于您的业务,老实说内置逻辑大部分时间可能不够用。对于“帖子”的日期来说,“几天前”是可以接受的,但我正在跟踪邮件中的包裹,说“您的包裹几天前已发货”就不够好了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接