【问题标题】:Is there a way to parse a relative date using Moment.js?有没有办法使用 Moment.js 解析相对日期?
【发布时间】:2015-06-06 12:50:59
【问题描述】:

Moment.js 是一个非常有用的 JavaScript 库,它提供了许多操作日期格式的函数。

为了创建 Moment 对象,可以简单地 parse a string moment("1995-12-25"); 或提供格式 moment("12-25-1995", "MM-DD-YYYY");

另一个功能允许我们使用relative dates : moment("1995-12-25").fromNow() // 19 years ago

但是,我找不到解析这样一个相对日期的方法。当我尝试moment("19 years ago") 时,它只返回Invalid date,并且它不存在任何标记来正确格式化日期。

有没有简单的方法来做到这一点?还是应该在 Github 上推荐一个缺失的功能?

【问题讨论】:

    标签: javascript date formatting momentjs


    【解决方案1】:

    刚找到chrono wile,想看看 NLP 是否已经在 momentjs 中实现。看起来它处理将 NLP 解析为日期,可用于创建 momentjs 日期。

    只需将字符串传递给函数 chrono.parseDate 或 chrono.parse。

    > var chrono = require('chrono-node')
    
    > chrono.parseDate('An appointment on Sep 12-13') 
    Fri Sep 12 2014 12:00:00 GMT-0500 (CDT)
    

    还有一个简单的例子来展示它是如何工作的

    代码

    const moment = require('moment')
    const chrono = require('chrono-node')
    
    let now = moment()
    console.log(now)
    let yrsAgo = chrono.parseDate("19 years ago")
    console.log(yrsAgo)
    let yrsAgoMoment = moment(yrsAgo)
    console.log(yrsAgoMoment)
    

    输出

    $node test.js
    moment("2017-06-30T08:29:20.938")
    1998-06-30T17:00:00.000Z
    moment("1998-06-30T12:00:00.000")
    

    【讨论】:

      【解决方案2】:

      这样做的唯一方法是moment().sub(19, 'years');

      你所问的暗示Natural language processing,这是整个计算机科学领域。

      【讨论】:

      • 所以这并不是真正“解析”日期,太糟糕了。那么我会在 Github 上推荐这个功能。但是,我不确定完全理解你的第二句话。我真的不明白为什么这样的解析器意味着使用像 NLP 这样的复杂技术。相对日期的格式总是相同的:例如3 years and 6 hours agoIn 1,4 months。识别关键字然后计算日期并不复杂,Moment.js 解析器已经做到了。
      • @Delgan - 它已被多次请求并被 moment.js 作者拒绝,因为它超出了核心库的范围。也没有人加紧为它制作插件。如果您有兴趣,请随时加紧! :) 主要的复杂性在于在多个语言环境中支持该功能,但也存在其他微妙的问题。
      【解决方案3】:

      最近在 github 上出现了一个插件,这是一个允许这种解析的插件:https://github.com/cmaurer/relative.time.parser

      我没有亲自尝试过,但我很快就会(在搜索相同的东西时发现它这个问题)。

      【讨论】:

      • 不幸的是,它不适用于我提供的示例,它是一个用于解析 +19years 例如的插件。不过谢谢分享。
      • 我的错误,我认为相对格式有一些灵活性。
      【解决方案4】:

      怎么样:

      moment.fn.parse = function(_relative, _format){
          var _modulo = moment.normalizeUnits(_format);
          return this.add(_relative, _modulo);
      }
      
      moment("30/08/2015", "DD/MM/YYYY").parse(-20, "years").format('DD/MM/YYYY'); // 30/08/1995
      moment("30/08/2015", "DD/MM/YYYY").parse(-2, "week").format('DD/MM/YYYY'); // 16/08/2015
      moment("30/08/2015", "DD/MM/YYYY").parse(-2, "d").format('DD/MM/YYYY'); // 28/08/2015
      

      【讨论】:

        【解决方案5】:

        我写了插件relative.time.parser。最初的意图是从石墨from/until 中解析相对时间,所以我只是在时间上进行“反向”。

        我也会考虑添加“NLP”用例。

        谢谢, 克里斯

        【讨论】:

        • 这和momentjs有什么关系?
        • 这是一个moment.js插件。
        • 感谢您的澄清,我以为您在谈论石墨插件。
        • 不用担心。如果这是今天发生在我们身上的最糟糕的事情,那就没事了。
        【解决方案6】:

        您可以使用时刻加上少量逻辑轻松做到这一点。在这里它工作得很好

        function parseSincUntilDate(dateStr, now = new Date()) {
          // inputs: 20 minutes ago, 7 hours from now, now, '', or UTC string
          if (moment(dateStr).isValid()) return moment(dateStr).toDate();
          const tokens = dateStr.split(' ');
          if (dateStr.includes('ago')) {
            return moment(now).subtract(tokens[0], tokens[1]).toDate();
          } else if (dateStr.includes('from now')) {
            return moment(now).add(tokens[0], tokens[1]).toDate();
          } else if (dateStr === 'now' || dateStr === '') {
            return new Date(now);
          }
          return moment(dateStr).toDate();
        }
        // to change relative date, pass it in second parameter
        

        【讨论】:

          【解决方案7】:

          从 Moment.js 1.0.0(2011 年 10 月)到当前:

          moment().add(7, 'days');
          moment().subtract(1, 'seconds');
          

          适用于年、季度、月、周、日、小时、分钟、秒和毫秒。

          https://momentjs.com/docs/#/manipulating/add/

          https://momentjs.com/docs/#/manipulating/subtract/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-04-04
            • 1970-01-01
            • 2014-04-06
            • 1970-01-01
            • 2019-03-31
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多