`moment.updateLocale`全部从24h到12h,反之亦然

时间:2018-01-09 20:02:51

标签: momentjs

我在设备上使用了momentjs。尽管locale例如是en_US,但设备设置可能会说使用24h格式。

我希望将默认语言环境设置为使用24h,这样任何给出12h的时刻格式都应该给出24h(反之亦然)。例如

  • moment.format('LT')提供"8:30 PM"
  • moment.format('LLLL')提供"Thursday, September 4, 1986 8:30 PM"

所以给出24h的任何格式都应该在12h内给出。我知道我可以轻松地使用大写HHH的格式,但我不知道当前的区域设置是LT还是LLLL等包括AM / PM。无论如何moment.updateLocale所有hHhhHH都有?

2 个答案:

答案 0 :(得分:3)

您可以使用localeData()longDateFormat()获取本地化格式令牌,并发现给定的区域设置是使用h(12h)还是H(24h)。

然后,您可以使用updateLocale轻松更改(例如,RegExp替换)LTSLLLL的本地化令牌。

您可以使用updateLocale内的meridiem键或以本地化格式删除a / A令牌来取消AM / PM显示。

这是一个实例:

['af' , 'ar-dz', 'ar-kw', 'ar-ly', 'ar-ma', 'ar-sa', 'ar-tn', 'ar', 'az', 'be', 'bg', 'bn', 'bo', 'br', 'bs', 'ca', 'cs', 'cv', 'cy', 'da', 'de-at', 'de-ch', 'de', 'dv', 'el', 'en-au', 'en-ca', 'en-gb', 'en-ie', 'en-nz', 'eo', 'es-do', 'es', 'et', 'eu', 'fa', 'fi', 'fo', 'fr-ca', 'fr-ch', 'fr', 'fy', 'gd', 'gl', 'gom-latn', 'he', 'hi', 'hr', 'hu', 'hy-am', 'id', 'is', 'it', 'ja', 'jv', 'ka', 'kk', 'km', 'kn', 'ko', 'ky', 'lb', 'lo', 'lt', 'lv', 'me', 'mi', 'mk', 'ml', 'mr', 'ms-my', 'ms', 'my', 'nb', 'ne', 'nl-be', 'nl', 'nn', 'pa-in', 'pl', 'pt-br', 'pt', 'ro', 'ru', 'sd', 'se', 'si', 'sk', 'sl', 'sq', 'sr-cyrl', 'sr', 'ss', 'sv', 'sw', 'ta', 'te', 'tet', 'th', 'tl-ph', 'tlh', 'tr', 'tzl', 'tzm-latn', 'tzm', 'uk', 'ur', 'uz-latn', 'uz', 'vi', 'x-pseudo', 'yo', 'zh-cn', 'zh-hk', 'zh-tw'].forEach(localeName => {
  // Get locale data
  let localeData = moment.localeData(localeName);
  // Get localized format tokens for LT and LTS
  let lt = localeData.longDateFormat('LT');
  let llll = localeData.longDateFormat('LLLL');
  // Replace 12h with 24h
  lt = lt.replace(/h/g, 'H');
  llll = llll.replace(/h/g, 'H');

  // Update locale with new values, supperssing am/pm output
  moment.updateLocale(localeName, {
    meridiem : (hour, minute, isLowercase) => '',
    longDateFormat : {
      LT: lt,
      LLLL: llll
    }
  });
  
  const m = moment({h: 15}).locale(localeName);
  console.log(localeName, m.format('LT'), m.format('LLLL'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment-with-locales.min.js"></script>

答案 1 :(得分:1)

这就是我所使用的,它不使用@Vincenzo上面的meridiem抑制技术,它只是取代了meridiem。它会努力在12h到24h之间恢复,如果之前是hh或只是h,则会检测到它。即使是资本A或更低a

const leading12hZero = {};
const lowerMeridiemPlaceholder = ' '.repeat(3);
const upperMeridiemPlaceholder = ' '.repeat(6);
export function updateTimeFormat(to24h) {
    // to24h - true to set to 24h ELSE false to set to 12h
    const { _abbr, _longDateFormat } = moment.localeData();

    let longDateFormat;
    if (to24h) {
        // set to 24h format
        longDateFormat = Object.entries(_longDateFormat).reduce((formatz, [token, format]) => {
            if (!(token in leading12hZero)) {
                if (format.includes('hh:')) {
                    leading12hZero[token] = true;
                } else {
                    leading12hZero[token] = false;
                }
            }
            formatz[token] = format.replace('hh:', 'HH:').replace('h:', 'HH:').replace('a', `[${lowerMeridiemPlaceholder}]`).replace('A', `[${upperMeridiemPlaceholder}]`);
            return formatz;
        }, {});
    } else {
        // set to 12h format
        longDateFormat = Object.entries(_longDateFormat).reduce((formatz, [token, format]) => {
            const shouldLeadingZero = leading12hZero[token];
            formatz[token] = format.replace('HH:', shouldLeadingZero ? 'hh:' : 'h:').replace('H:', shouldLeadingZero ? 'hh:' : 'h:').replace(`[${lowerMeridiemPlaceholder}]`, 'a').replace(`[${upperMeridiemPlaceholder}]`, 'A');
            return formatz;
        }, {});
    }

    moment.updateLocale(_abbr, { longDateFormat });
}

moment.prototype._formatOriginal = moment.prototype.format;
moment.prototype.format = function(str) {
    return moment.prototype._formatOriginal.call(this, str).replace(lowerMeridiemPlaceholder, '').replace(`${lowerMeridiemPlaceholder} `, '').replace(upperMeridiemPlaceholder, '').replace(`${upperMeridiemPlaceholder} `, '');
}