【问题标题】:add items into two arrays (future and past dates) based on date根据日期将项目添加到两个数组(未来和过去的日期)中
【发布时间】:2015-02-13 00:50:28
【问题描述】:

我正在尝试找到一种将帖子分类为两个数组的方法:即将发布的和当前的(即将发布的帖子在未来,而当前的帖子已经发布)。

所有帖子都有一个 schedulePubDate,它是一个日期字符串,格式为 YYYY-MM-DDT00:00:00。今天的日期必须是一个 Date 对象,因为它需要保持相关性(我正在使用 moment())

是否可以比较这两个不同的东西而不必使用 .split 并分别比较月/日/年

 angular.forEach(data.items, function (key, index) {
   if (moment(key.scheduledPubDate) > moment()) {
       $scope.upcomingPosts.push(item[index]);
   } else if (moment(key.scheduledPubDate) <= moment()) {
       $scope.currentPosts.push(item[index]);
   };
 });

【问题讨论】:

  • 虽然这不是一个完整的答案,但您应该考虑将ng-repeat 与过滤器和指令一起使用,而不是使用 forEach - 调查一下
  • 我没想过这样做。但是这次它对我不起作用,因为我没有显示数据,而是将它们分成两个数组,但我很感激这个提醒!我总是忘记过滤器
  • docs.angularjs.org/api/ng/filter/orderBy 很确定你也可以在非 UI 的东西上做 ng-repeat。它只返回按您包含的模型参数排序的数组副本
  • 您可以使用moment(theDateStr, theFormatStr); 将日期解析为字符串。完成后,您可以使用&lt;&gt; 比较日期。没有内置任何东西来比较字符串日期,你需要解析它们。
  • 字符串没有时区,您希望将其视为 UTC 还是本地?标准不同,所以你不能依赖它。

标签: javascript angularjs momentjs


【解决方案1】:

大概您希望将字符串视为 UTC,一个简单的解析器是:

// Expected format YYYY-MM-DDT00:00:00
function parseUTC(s) {
  var b = s.split(/\D/);
  return new Date(Date.UTC(b[0], b[1]-1, b[2], b[3], b[4], b[5]));
}

请注意,这不允许无效日期。如果需要,如果需要代码,则额外添加一行。所以现在你可以这样做了:

if (parseUTC(key.scheduledPubDate) > new Date()) // or Date.now()

你真的不需要 moment.js。

【讨论】:

    【解决方案2】:

    JavaScript 的内置 Date object 将在这里为您提供帮助。

    var date = Date.parse('2014-01-21T12:45:13');
    date < Date.now() // true
    

    为了举例,我们假设items 是一个帖子数组:

    var items = [{
        scheduledPubDate: '2014-01-21T12:45:13'
        // ...other keys here
    }, {
        scheduledPubDate: '2017-03-01T15:21:00'
    } // ...and so on
    ];
    

    然后对items 进行reduce 操作可以对帖子进行分类:

    var posts = items.reduce(function (memo, item) {
        memo[Date.parse(item.scheduledPubDate) <= Date.now() ? 'current' : 'upcoming'].push(item);
        return memo;
    }, { current: [], upcoming: [] });
    

    现在posts.current 将包含来自items 的所有帖子的数组,其中scheduledPubDate 在当前日期之前,posts.upcoming 将包含所有预定帖子的数组。

    编辑为使用Date.parse,以避免 RobG 指出的不可靠行为。这要求所有日期都采用您指定的YYYY-MM-DDT00:00:00 格式;如果不是这种情况,则需要另一种解决方案。

    【讨论】:

    • javascript 中没有“日期类”。有Date objects。不要使用 Date 构造函数来解析字符串,它是不可靠的。您提出的格式将被某些脚本引擎(符合 ES5)视为本地格式,在其他引擎(符合 ECMA-262 ed 6 草案)和 NaN 或其他完全不同的东西中视为本地格式。
    • 感谢您指出这一点。我已将答案更新为使用Date.parse,因为问题指出所有日期字符串的格式均为YYYY-MM-DDT00:00:00
    【解决方案3】:

    你必须指定字符串的日期格式

     var format = "YYYY-MM-DDT00:00:00";
     angular.forEach(data.items, function (key, index) {
       if (moment(key.scheduledPubDate, format) > moment()) {
         $scope.upcomingPosts.push(item[index]);
       } else if (moment(key.scheduledPubDate, format) <= moment()) {
         $scope.currentPosts.push(item[index]);
       };
     });
    

    工作示例(参见 console.log):http://jsbin.com/fejaxiguce/1/edit?html,output

    【讨论】:

      【解决方案4】:

      首先以任意顺序创建一个元素数组,然后使用 .sort() 方法。

      http://www.w3schools.com/jsref/jsref_sort.asp

      var points = [40, 100, 1, 5, 25, 10];
      points.sort(function(a, b){return a-b});  
      

      只需用您自己的逻辑替换上述逻辑即可。上面的 a 和 b 可以是对象。

      【讨论】:

      • 这是个好主意,但我并没有试图按顺序排列它们。我更关心 1)如何比较不同格式的日期 2)是否可以将字符串转换为日期或 3)是否可以比较这两个不同的东西而不必使用 .split 和比较月/日/年分别
      • 请不要参考 W3Schools。使用language specification 作为规范性参考,Mozilla Developer Network (MDN) 或类似的例子作为示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      • 2017-08-19
      • 2013-04-29
      • 2021-09-07
      相关资源
      最近更新 更多