Intl.DateTimeFormat node 和 devtools 的区别

Intl.DateTimeFormat difference beetween node and devtools

我今天正在为此功能编写单元测试:

/**
 * recives a timestamp and format to 'yyyy/mm/dd hh:mm'
 */
function formatCurrentDate(date) {
  return Intl.DateTimeFormat('ja-JP',
    {
      hour: '2-digit',
      minute: '2-digit',
      year: 'numeric',
      month: '2-digit',
      day: '2-digit'
    }).format(date);
}

通过此测试:

test('it should format the current date', () => {
  expect(formatCurrentDate(new Date().getTime())).toMatch(new RegExp(/^\d{4}\/\d{2}\/\d{2}\s{1}\d{2}\:\d{2}$/));
}); 

但总是失败,因为节点 returns 对我来说是不同的日期格式

所以我刚刚在 devtools 上意识到 运行nig formatCurrentDate() 我得到了正确的格式:'2020/08/25 14:50'

但是当我 运行 在我的 cmd 上使用相同的功能时(输入节点并粘贴功能)我得到:'2020-08-25 14:50'

为什么会这样??

Intl.DateTimeFormat 尝试提供基于语言代码的日期组件的文化敏感格式。没有将语言代码映射到格式的明确规范或标准,它取决于实现。此外,如果不支持特定语言,则实现可能会回退到默认格式。所以不同的实现很可能会为相同的语言代码和选项提供不同的格式。

所以依靠Intl.DateTimeFormat来格式化日期并期望它有一个精确的格式并不是一个好主意。您可以使用 formatToParts method 来获取适当的部分,然后手动将它们放入您想要的格式。

如果您想要特定的格式,您应该使用定制的函数或格式库手动创建它,您可以自己编写这些函数或格式库,也可以使用网络上提供的众多格式之一。在 Whosebug 上已经有很多关于该主题的问题和答案。

PS。 post 代码作为可运行的代码段很有帮助,例如

/**
 * recives a timestamp and format to 'yyyy/mm/dd hh:mm'
 */
function formatCurrentDate(date = new Date()) {
  return Intl.DateTimeFormat('ja-JP',
    {
      hour: '2-digit',
      minute: '2-digit',
      year: 'numeric',
      month: '2-digit',
      day: '2-digit'
    }).format(date);
}

console.log(formatCurrentDate());