使用Moment.js的区域设置和特定日期格式

时间:2014-12-08 14:24:53

标签: javascript localization locale momentjs

我在项目中使用Moment.js,格式化日期如下:

var locale = window.navigator.userLanguage || window.navigator.language;
moment.locale(locale);
someDate.format("L");

它运作良好但有时我需要显示没有年份的日期。我不能使用像someDate.format("MM/DD")这样的内容,因为在某些语言中它应该是someDate.format("DD/MM")。我需要一些像L,LL,LLL这样但没有年份的东西。

我该怎么办?

LTS : 'h:mm:ss A',
LT : 'h:mm A',
L : 'MM/DD/YYYY',
LL : 'MMMM D, YYYY',
LLL : 'MMMM D, YYYY LT',
LLLL : 'dddd, MMMM D, YYYY LT'

4 个答案:

答案 0 :(得分:24)

好。这有点可怕,但你知道它会是。

首先,您可以访问(例如)'L'的实际格式字符串:

var formatL = moment.localeData().longDateFormat('L');

接下来,你可以通过明智的正则表达式替换来进行一些手术:

var formatYearlessL = formatL.replace(/Y/g,'').replace(/^\W|\W$|\W\W/,'');

(也就是说:删除YYYY,加上删除后留下的孤立分隔符)

然后您可以在片刻格式调用中使用新的格式字符串:

someDate.format(formatYearlessL);

这必然会做出一些假设:

  • 区域设置的月份+日数字格式的顺序与该区域设置的年份+月份+日期格式的顺序相匹配,并删除年份。
  • 短格式仅在月份和日期之间使用分隔符(没有前导/尾随分隔符)。
  • 短数字日期格式的分隔符始终为非字母数字。
  • 格式由数字元素和分隔符组成,而不是带有文章的句子格式(请参阅RGPT下面关于西班牙语和葡萄牙语的评论,这些评论也适用于其他语言的长格式)。

在对locale/*.js的快速回顾中,这些假设适用于我检查的每个区域设置文件,但可能存在一些违反它们的区域设置。 (ETA:下面的评论指出德国短日期格式违反了第二个假设)

作为一个额外的重要警告,这可能是脆弱的。未来版本的moment.js完全有可能改变longDateFormat中当前数据的位置...

答案 1 :(得分:2)

据我了解,您可以使用MomentJS属性更改特定语言的日期格式(不含年份)https://momentjs.com/docs/#/customization/long-date-formats/

示例:

moment.updateLocale('en', {
  longDateFormat: {
    LLL: "MMMM Do, LT", // Oct 6th, 4:27 PM
  }
});

moment.updateLocale('ru', {
  longDateFormat: {
    LLL : 'D MMMM, HH:mm', // 6 окт., 16:27
  }
});

答案 2 :(得分:0)

该库无法轻松添加新格式,因为它们已针对我们无法覆盖的正则表达式进行了验证(var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;)。

但是,我们可以覆盖format函数,以便将新格式转换为Moment可以识别的令牌。

例如,让我们添加一个称为“ LMD”的新自定义格式。 首先,我们需要为每个要使用的语言环境定义它:

moment.updateLocale('en', {
   longDateFormat: {
       LMD: 'MMMM D'
   }
});

moment.updateLocale('fr', {
    longDateFormat: {
        LMD: 'D MMMM'
    }
});

然后,我们将覆盖原始格式函数,并将inputString(“ LMD”)转换为我们先前定义的真实令牌。 之后,我们只需调用原始函数,然后让Moment照常执行其工作:

var originalMomentFormat = moment.prototype.format;
moment.prototype.format = function (inputString) {
    if (inputString === 'LMD') { // check for your custom types here. maybe use constants or whatever
        inputString = moment.localeData().longDateFormat(inputString);
    }
    return originalMomentFormat.apply(this, [inputString]);
};

用法示例:

moment(someDate).format('LMD');

答案 3 :(得分:0)

一种选择可能是使用CLDR data并保留格里高利数据并查找main.{locale}.dates.calendars.gregorian.dateTimeFormats.availableFormats。您可能想要的是Md

我可能建议您使用Globalize库使这一切变得容易。您会注意到,如果将日期格式设置为skeleton,则库可以为您完成所有本地化操作。

例如:

.dateFormatter({ skeleton: "GyMMMd" })( new Date() )
// > "Nov 30, 2010 AD"