【问题标题】:Moment Display Birthdate Relative to Current Days DAYOFYEARMoment 显示相对于当前日期的生日 DAYOFYEAR
【发布时间】:2017-03-02 12:11:58
【问题描述】:

我在我的 Angular 应用程序中使用 moment(),我需要显示相对于一周中当前日期的生日(无论年份如何)。我的服务器将以YYYY-MM-DD 格式发送本周即将到来的生日列表,我希望这样显示(考虑到今天的日期是 2017 年 3 月 2 日):

BirthDate  - Display it to this year's day of the week
2014-03-01 - Yesterday
2016-03-02 - Today
2015-03-03 - Tomorrow
2014-03-04 - Saturday
etc...

在我的 Angular 1.5 视图中,我可以像这样将数据发送到 dayCheck 函数:

<p ng-repeat="person in birthdays">
  Name: {{person.name}} <br>
  When: {{vm.dayCheck(person.date)}}
</p>

function dayCheck(date) {
   return moment(date).format('DD'); // ?? How can I return the days relative to user's day from this year??
}

我的回答:

这是我发布问题后的想法。它看起来并不优雅,我相信有更好的方法来做到这一点。但我必须解决的工作代码是:

function dayCheck(date) {
    var returnData = '';
    var birthDayDate = moment(date).format('DD');
    if (birthDayDate == moment().format('DD')) {
        var returnData = 'Today';
    }
    else if (birthDayDate == moment().subtract(1, 'days').format('DD')) {
        var returnData = 'Yesterday';
    }
    else if (birthDayDate == moment().add(1, 'days').format('DD')) {
        var returnData = 'Tomorrow';
    }
    else {
        var momentDate = moment(date);
        var month = momentDate.format('MM');
        var date  = momentDate.format('DD');
        var currentMonth = moment().format('MM');
        if (currentMonth == 12 && month == 1) {
            var year = moment().add(1, "years").year();
        }
        else if (currentMonth == 1 && month == 12) {
            var year = moment().subtract(1, "years").year();
        }
        else {
            var year = moment().year();
        }
        var dateFormat = year + '-' + month + '-' + date;
        var returnData = moment(dateFormat).format('dddd');
    }
    return returnData;
}

如果有更好、更优雅的方式来完成上述操作,请告诉我。如果生日是闰年的 2 月 29 日,我也怀疑上述方法会失败。

【问题讨论】:

    标签: javascript angularjs date momentjs


    【解决方案1】:

    您可以简单地使用时刻calendar()。要自定义格式,请参阅docs。这是一个工作示例:

    var input = ['2014-03-01',
    '2016-03-02',
    '2015-03-03',
    '2014-03-04'];
    
    function dayCheck(date) {
      var thisYear = moment().year();
      var mom = moment(date).year(thisYear);
      return mom.calendar(null, {
        sameDay: '[Today]',
        nextDay: '[Tomorrow]',
        nextWeek: 'dddd',
        lastDay: '[Yesterday]',
        lastWeek: '[Last] dddd',
        sameElse: 'DD/MM/YYYY'
      });
    }
    
    for(var i=0; i<input.length; i++){
      console.log(dayCheck(input[i]));
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 天哪!这真是太好了!!!正是我所追求的。我的方法就像指环王,而你的方法又简单又完美!非常感谢@VincenzoC!!
    • 很高兴我的回答对您有所帮助。我没有足够的时间来测试闰年,它是否提供了正确的输出?这些案例的预期结果是什么?
    • 当日期是闰年的 2 月 29 日时,它会显示 3 月 1 日的日期作为输出。作为测试,我将计算机日期更改为 2 月 24 日,然后将 2 月 29 日日期显示为“星期三”,这实际上是今年的 3 月 1 日。我认为这是在这种情况下所需的输出。一切都很好。
    • @Neel — 如果您尝试使用无效日期字符串(如“2017-02-29”(但不使用 new Date(2017,1,29) 等值)创建日期),结果应该 是一个无效的日期。
    • @Neel——我看到了你的困境:在非闰年的 2 月 29 日生日该做什么。不同的司法管辖区有不同的规定:有些是 2 月 28 日,有些是 3 月 1 日,个人喜好相同。走哪条路没有正确或错误的答案。
    【解决方案2】:

    为了完整起见,不是每个人都使用 moment.js,如果没有库,它只需要几个简单的函数来解析字符串、获取日期名称等:

    var myLib = {date: {
      // If notStrict is true, don't check for a valid date
      parseISOLocal: function (s, notStrict) {
        var b = s.split(/\D/);
        var d = new Date(b[0], --b[1], b[2]);
        return notStrict || (d && d.getMonth() == b[1])? d : new Date(NaN);
      },
    
      daysDiff: function (a, b) {
        var diff = new Date(a).setHours(12,0,0,0) - new Date(b).setHours(12,0,0,0) ;
        return Math.round(diff/8.64e7);
      },
    
      dayName: function (d) {
        return d.toLocaleString(undefined, {weekday:'long'});
      }
    }};
    
    ['2014-03-01','2016-03-02','2015-03-03','2010-03-04','2007-03-05',
     '1914-03-06','1987-03-07','1800-03-08','1991-03-24','2004-01-04',
     '2000-02-29'].forEach(function(s) {
      s = s.replace(/^\d{4}/,new Date().getFullYear());
      var d = myLib.date.parseISOLocal(s, true);
      var diff = myLib.date.daysDiff(d, new Date());
      if (diff > 7 || diff < -7) msg = d.toLocaleString(undefined,{day:'numeric',month:'long'});
      else if (diff <  -1) msg = 'Last ' + myLib.date.dayName(d);
      else if (diff == -1) msg = 'Yesterday (' + myLib.date.dayName(d) + ')';
      else if (diff ==  0) msg = 'Today';
      else if (diff ==  1) msg = 'Tomorrow (' + myLib.date.dayName(d) + ')';
      else                 msg = 'Next ' + myLib.date.dayName(d);
      console.log(d.toLocaleString(undefined,{day:'numeric', month:'short', year:'numeric'})
                  + ' : ' + msg);
    })

    处理 2 月 29 日并不容易,这只是让它滚动到 3 月 1 日,这可能并不适合所有人。

    【讨论】:

    • 谢谢@RobG 如果没有moment.js,这些功能肯定会有所帮助。一个非常好的替代解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-08-04
    • 2014-06-03
    • 2014-05-22
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2018-07-05
    相关资源
    最近更新 更多