【问题标题】:Extract a date suffix with MomentJS to make it superscript使用 MomentJS 提取日期后缀使其成为上标
【发布时间】:2015-09-18 13:24:10
【问题描述】:

我遵循严格的用户界面指南,我需要在上标 (<sup>) 中显示日期后缀:

18th 2015 年 9 月

MomentJS 有很多格式化日期的功能,但不幸的是,它似乎不允许我们在不包括前面的数字的情况下提取日期后缀(上例中的 th 位)...

                Token    Output
Month           Mo       1st 2nd ... 11th 12th
Day of Month    Do       1st 2nd ... 30th 31st
Day of Year     DDDo     1st 2nd ... 364th 365th
...

目前我正在使用以下方法去除后缀之前的数值:

date.format("Do").replace(/\d/g, "");
--> "18th" -> "th"

但问题是,当必须显示“2015 年 9 月 18 日”之类的内容时,这会变得混乱,因为我必须使用三个单独的 format() 调用:

var dateSuffix = "<sup>" + date.format("Do").replace(/\d/g, "") + "</sup">;
date.format("DD") + dateSuffix + date.format("MMMM YYYY");
--> "18<sup>th</sup> September 2015"

理想情况下,我希望完全避免使用replace(),而是使用与此类似的东西,但将Do 部分替换为仅后缀:

moment(new Date()).format("DD<\\sup>Do</\\sup> MMMM YYYY");
--> "18<sup>18th</sup> September 2015"

MomentJS 是否有任何功能可以自行提取日期后缀?

【问题讨论】:

    标签: javascript momentjs


    【解决方案1】:

    我为自己的项目查看了这个,但决定使用正则表达式解决方案。

    myDate.format( 'Do MMMM YYYY' ).replace( /(\d)(st|nd|rd|th)/g, '$1<sup>$2</sup>' );
    

    我很欣赏 OP 希望避免使用正则表达式,但这是一个可能对其他人有益的简单解决方案。

    【讨论】:

      【解决方案2】:

      我不认为 MomentJS 具有您正在寻找的功能;我会说你应该去 MomentJS 网站并将其作为功能建议提交。你永远不知道,它甚至可能会被实施。

      同时,另一种选择可能是使用 MomentJS 中的配置选项来更改 Ordinal 字符串(即后缀),以便它们包含 &lt;sup&gt; 标记。

      在此处查看 MomentJS 手册中的相关部分:http://momentjs.com/docs/#/customization/ordinal/

      你最终会编写一个如下所示的函数:

      moment.locale('en', {
          ordinal: num => {
              const b = num % 10;
              const output = (~~(num % 100 / 10) === 1) ? 'th' :
                  (b === 1) ? 'st' :
                      (b === 2) ? 'nd' :
                          (b === 3) ? 'rd' : 'th';
              return num + '<sup>' + output + '</sup>';
          },
      });
      

      上面的例子直接取自 MomentJS 的手册,只是修改了 return 行。

      【讨论】:

      • 这很有趣,我不知道 Moment 允许这样自定义!
      • 该功能主要用于本地化(即翻译),但也可以用于此类事情。
      • 截至 2.12 时刻,函数为 moment.updateLocale('en',...)
      【解决方案3】:

      上面的答案都很好,但是因为我使用的 react-moment 对我不起作用。

      我只是使用了 react-moment 中的内置过滤器功能,在文档 here 中进行了很好的解释。

      我写了一个简单的字符串替换函数如下(注意我放置函数的位置):

      ...render() {
          const toSuperFilter = (sup) => {
              let res=sup.replace(/(?<=[0-9])(?:st)/i, "ˢᵗ");
              res=res.replace(/(?<=[0-9])(?:nd)/i, "ⁿᵈ");
              res=res.replace(/(?<=[0-9])(?:rd)/i, "ʳᵈ");
              res=res.replace(/(?<=[0-9])(?:th)/i, "ᵗʰ");
              return res
          }
          return (...
      

      然后在子组件的那一刻,我是这样传递的:

      <Moment filter={toSuperFilter} format="Do MMM, YYYY">
          {`${date_variable}`}
      </Moment>
      

      像魅力一样工作!结果如下:

      编辑:我之前忘记考虑月份名称,因此 8 月的 st 在测试期间也被替换了 :) 我添加了一个在数字后检查 st 的组并解决了它。使用正则表达式对任何其他更优雅的解决方案开放。我无法使用该标签,因为它是 react-moment 中的一个字符串。让我知道是否有人可以让这部分工作。

      【讨论】:

        【解决方案4】:
        D DD        1..31       Day of month
        Do          1st..31st   Day of month with ordinal
        DDD DDDD    1..365      Day of year
        

        您可以将Do 用于带序号的一天。

        我用:

        moment().format('Do MMMM YYYY');
        

        【讨论】:

        • Do 不像问题所问的那样提取日期序数,它同时提供日期和序数。
        猜你喜欢
        • 2011-01-04
        • 2014-12-11
        • 1970-01-01
        • 1970-01-01
        • 2014-09-30
        • 1970-01-01
        • 1970-01-01
        • 2020-07-19
        相关资源
        最近更新 更多