Javascript Moment.js 的区域设置和特定日期格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27360102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Locale and specific date format with Moment.js
提问by Jekyll
I am using Moment.js in my project and formatting dates as follows:
我在我的项目中使用 Moment.js 并按如下方式格式化日期:
var locale = window.navigator.userLanguage || window.navigator.language;
moment.locale(locale);
someDate.format("L");
It works well but sometimes I need show a date without a year. I can't use something like someDate.format("MM/DD")because in some languages it should be someDate.format("DD/MM"). I need something like L,LL,LLLbut without the year.
它运作良好,但有时我需要显示一个没有一年的日期。我不能使用类似的东西,someDate.format("MM/DD")因为在某些语言中它应该是someDate.format("DD/MM"). 我需要类似L,LL,LLL但没有年份的东西。
What can I do?
我能做什么?
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'
采纳答案by S McCrohan
Okay. This is a little awful, but you knew it was going to be.
好的。这有点可怕,但你知道它会是。
First, you can access the actual format string for (for instance) 'L':
首先,您可以访问(例如)的实际格式字符串'L':
var formatL = moment.localeData().longDateFormat('L');
Next, you can perform some surgery on it with judicious regex replacement:
接下来,您可以使用明智的正则表达式替换对其进行一些手术:
var formatYearlessL = formatL.replace(/Y/g,'').replace(/^\W|\W$|\W\W/,'');
(Which is to say: Remove YYYY, plus the orphaned separator left by its removal)
(也就是说:删除YYYY,加上删除后留下的孤立分隔符)
Then you can use your new format string in a moment format call:
然后你可以在一个 moment 格式调用中使用你的新格式字符串:
someDate.format(formatYearlessL);
This necessarily makes some assumptions:
这必然做出一些假设:
- The order of the month + day numeric format for a locale matches the order for the year + month + day format for that locale, with the year removed.
- The short form uses separators only between month and day (no leading / trailing separators).
- The separator for a short numeric date format is always non-alphanumeric.
- The format consists of numeric elements and separators, rather than a sentence-form format with articles (see RGPT's comment below about Spanish and Portugese, which will also apply to long formats in some other languages).
- 语言环境的月 + 日数字格式的顺序与该语言环境的年 + 月 + 日格式的顺序相匹配,但删除了年份。
- 简短形式仅在月和日之间使用分隔符(没有前导/尾随分隔符)。
- 短数字日期格式的分隔符始终为非字母数字格式。
- 该格式由数字元素和分隔符组成,而不是带有文章的句子形式格式(请参阅下面关于西班牙语和葡萄牙语的 RGPT 评论,这也适用于其他一些语言的长格式)。
On a quick review of locale/*.js, these assumptions hold true for every locale file I examined, but there may be some locales that violate them. (ETA: a comment below points out that a German short date format violates the second assumption)
快速回顾locale/*.js一下,这些假设适用于我检查过的每个语言环境文件,但可能有一些语言环境违反了它们。(ETA:下面的评论指出德国短日期格式违反了第二个假设)
As an additional important caveat, this is likely to be fragile. It is entirely possible that a future version of moment.js will change the location of the data currently in longDateFormat...
作为一个额外的重要警告,这可能是脆弱的。未来版本的 moment.js 完全有可能改变当前数据的位置longDateFormat......
回答by MegaCasper
As far as I understand, you can change the date format(without year) for specific languages using MomentJS properties https://momentjs.com/docs/#/customization/long-date-formats/
据我了解,您可以使用 MomentJS 属性更改特定语言的日期格式(不含年份)https://momentjs.com/docs/#/customization/long-date-formats/
Example:
例子:
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
}
});
回答by Emilie
The library doesn't make it easy to add new formats because they are validated against a regex that we cannot override (var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;).
该库无法轻松添加新格式,因为它们已根据我们无法覆盖的正则表达式 ( var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;)进行验证。
However, we can override the format function in order to transform our new format into tokens that Moment recognizes.
但是,我们可以覆盖 format 函数,以便将我们的新格式转换为 Moment 识别的标记。
For example, let's add a new custom format called "LMD". First we need to define it for every locale we want to use:
例如,让我们添加一个名为“LMD”的新自定义格式。首先,我们需要为我们想要使用的每个语言环境定义它:
moment.updateLocale('en', {
longDateFormat: {
LMD: 'MMMM D'
}
});
moment.updateLocale('fr', {
longDateFormat: {
LMD: 'D MMMM'
}
});
Then we override the original format function and transform the inputString("LMD") into the real tokens we previously defined.
After that we just call the original function and let Moment do its job as usual:
然后我们覆盖原始格式函数并将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]);
};
Example usage:
用法示例:
moment(someDate).format('LMD');
回答by cjbarth
One option might be to use the CLDR dataand get a hold of the Gregorian data and look up main.{locale}.dates.calendars.gregorian.dateTimeFormats.availableFormats. The one you probably want is Md.
一种选择可能是使用CLDR 数据并获取格里高利数据并查找main.{locale}.dates.calendars.gregorian.dateTimeFormats.availableFormats. 您可能想要的是Md.
I might suggest that you use the Globalizelibrary to make this all easier. You'll note that if you set the date format you want as a skeleton, the library can do all the localization for you.
我可能建议您使用Globalize库来简化这一切。您会注意到,如果您将所需的日期格式设置为skeleton,库可以为您完成所有本地化。
For example:
例如:
.dateFormatter({ skeleton: "GyMMMd" })( new Date() )
// > "Nov 30, 2010 AD"

