簡體   English   中英

Moment.js 的區域設置和特定日期格式

[英]Locale and specific date format with Moment.js

我在我的項目中使用 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類的東西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'

好的。 這有點可怕,但你知道它會是。

首先,您可以訪問(例如) 'L'的實際格式字符串:

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

接下來,您可以使用明智的正則表達式替換對其進行一些手術:

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

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

然后你可以在一個 moment 格式調用中使用你的新格式字符串:

someDate.format(formatYearlessL);

這必然做出一些假設:

  • 語言環境的月 + 日數字格式的順序與該語言環境的年 + 月 + 日格式的順序相匹配,但刪除了年份。
  • 簡短形式僅在月和日之間使用分隔符(沒有前導/尾隨分隔符)。
  • 短數字日期格式的分隔符始終為非字母數字格式。
  • 該格式由數字元素和分隔符組成,而不是帶有文章的句子形式格式(請參閱下面關於西班牙語和葡萄牙語的 RGPT 評論,這也適用於其他一些語言的長格式)。

快速回顧一下locale/*.js ,這些假設適用於我檢查過的每個語言環境文件,但可能有一些語言環境違反了它們。 (ETA:下面的評論指出德國短日期格式違反了第二個假設)

作為一個額外的重要警告,這可能是脆弱的。 未來版本的 moment.js 完全有可能改變當前longDateFormat數據的位置......

據我了解,您可以使用 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
  }
});

該庫無法輕松添加新格式,因為它們已根據我們無法覆蓋的正則表達式進行驗證 ( 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');

一種選擇可能是使用CLDR 數據並獲取公歷數據並查找main.{locale}.dates.calendars.gregorian.dateTimeFormats.availableFormats 您可能想要的是Md

我可能建議您使用Globalize庫來簡化這一切。 您會注意到,如果您將所需的日期格式設置為skeleton ,該庫可以為您完成所有本地化。

例如:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM