【问题标题】:local client-side JavaScript numeric date format (in browser)本地客户端 JavaScript 数字日期格式(在浏览器中)
【发布时间】:2021-04-11 15:58:03
【问题描述】:

因此,对于如何在特定于用户区域设置的客户端 JavaScript 中获取数字日期格式,我找不到一个好的答案。例如。如果您的语言是“en-US”,我想获得“MM/DD/YYYY”。

【问题讨论】:

  • 仅供参考,这个问题专门关于获取格式 with 占位符作为字符串,而不是格式化日期。

标签: javascript date format client-side date-formatting


【解决方案1】:

虽然很难确定用户的语言环境,但我们可以确定用户的首选语言并将其传递给 Intl.DateTimeFormat() 构造函数以创建日期格式化程序。

Date 对象传递给格式化程序的format 函数,以将日期格式化为预先指定的条件。

// Function that returns an instance of the DateTimeFormat constructor.
const createDateFormatter = () => new Intl.DateTimeFormat([], {
  year: '2-digit',
  month: '2-digit',
  day: '2-digit'
});

// Current date of today.
const date = new Date();

// Create a new formatter.
const dateFormatter = createDateFormatter();

// Format the date.
const formattedDate = dateFormatter.format(date);
console.log(formattedDate);

【讨论】:

  • 是否有任何理由使用 navigator.languages 而不是 'default'?
  • 嗯,不是真的。我忽略了空数组的可能性。不过,由于您的问题,我确实发现了 locale negotiation,这是我今天学到的新东西。虽然它不适用于这种情况,因为navigator.languages 可能与浏览器中的它可用的语言环境 相同。
  • 注意到关于 Intl 对象的“语言环境”的使用不幸与ECMA-402 中的“语言和文化”相混淆,它实际上代表一种语言(并且忽略了超过每种语言和地方一种文化)。我认为 Intl.DateTimeFormat 的唯一合理用途是以适当的语言和日历获取日期部分,然后以明确的顺序对其进行格式化。依靠带有扩展的语言来做到这一点是令人担忧的。
  • @RobG 我最初也希望默认设置能够正常工作。出于某种原因,它不适合我......即使我在偏好中设置了 en-GB,它也会选择 en-US
  • 我认为如果您只需要以用户首选格式格式化的日期,那么toLocaleString 是最好的解决方案。在这种情况下,我特别需要带有占位符的格式
【解决方案2】:

Date.toLocaleDateString 可以传递给options {year: 'numeric', month: '2-digit', day: '2-digit',} 以将日期格式化为最接近用户区域设置的数字格式。

要获得带有“YYYY”、“MM”和“DD”占位符的日期格式,您可以用相应的占位符字符串替换特定的年、月和日。

// Replace with date format e.g. 'MM/DD/YYYY'
const FALLBACK_DATE_FORMAT = 'your fallback date format';

// Memoize return value
let cachedNumericFixedWidthDateFormat = null;

function getNumericFixedWidthDateFormat() {
    if (cachedNumericFixedWidthDateFormat !== null) {
        return cachedNumericFixedWidthDateFormat;
    }

    let dateFormat;
    try {
        const dummyDate = new Date();
        dummyDate.setFullYear(1984);
        dummyDate.setMonth(0);
        dummyDate.setDate(23);

        dateFormat = dummyDate.toLocaleDateString(undefined, {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
        }).replace('1984', 'YYYY').replace('01', 'MM').replace('23', 'DD');
    } catch (err) {
        // TODO: Monitor errors!

        return FALLBACK_DATE_FORMAT;
    }

    if (checkIsValidDateFormat(dateFormat)) {
        cachedNumericFixedWidthDateFormat = dateFormat;

        return dateFormat;
    } else {
        // TODO: Add monitoring!

        return FALLBACK_DATE_FORMAT;
    }
}

function checkIsValidDateFormat(dateFormat) {
    const yearCharsMatches = dateFormat.match(/YYYY/g);
    const monthCharsMatches = dateFormat.match(/MM/g);
    const dayCharsMatches = dateFormat.match(/DD/g);
    const digitCharMatches = dateFormat.match(/[0-9]/g);

    return yearCharsMatches !== null && yearCharsMatches.length === 1
        && monthCharsMatches !== null && monthCharsMatches.length === 1
        && dayCharsMatches !== null && dayCharsMatches.length === 1
        && digitCharMatches === null;
}

// Output for Mozilla Firefox 87.0 on Ubuntu 20.04:
//     en-US: 'MM/DD/YYYY'
//     de-DE: 'DD.MM.YYYY'
//     es-ES, es-AR, en-GB: 'DD/MM/YYYY'
console.log(getNumericFixedWidthDateFormat());
original TypeScript playground

【讨论】:

  • navigator.language 可能会或可能不会返回用户的首选语言,并且用户可能期望与返回的语言相关联的格式不同。使用明确的格式要好得多。
  • 感谢您的信息。似乎是一个公平的评估:)虽然没有任何方法可以更好地适应用户的设置,但这有点糟糕
  • @RobG 我刚刚发现你可以直接将选项传递给Date.toLocaleDateString,而无需使用navigator.language。我没有做足够的研究来告诉你toLocaleDateString 是否可靠——它可能和navigator.language 有同样的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-20
  • 2021-04-23
  • 2016-03-21
  • 2014-07-26
  • 2012-11-09
相关资源
最近更新 更多