如何使用NodeJS将UTC日期格式化为`YYYY-MM-DD hh:mm:ss`字符串?

354

我想用 NodeJS 将一个 Date 格式化为以下字符串格式:

var ts_hms = new Date(UTC);
ts_hms.format("%Y-%m-%d %H:%M:%S");

如何做到这一点?


4
没有任何库的话,这有点麻烦。我建议使用datejs - Peter Olson
8
或者 momentjs - Mustafa
1
Datejs和Tempus都不是Node库(尽管它们可以与Node一起使用,但无法使用npm库安装程序)。由于没有人将它们作为实际答案提供,所以我自己完成了这个任务。 - Julian Knight
为什么不直接使用简单的 new Date().toUTCString() - hellboy
1
@RobG - 实际上,他在问题中并没有说他不想要一个库,只是需要一个答案,我的评论(来自4年前!)是为了鼓励人们真正给出答案而不是评论。从我的回答中可以看出,我很清楚有很多库可用,我等了一个星期看看是否还有其他人会给出任何答案。超过4年后的这种批评可能并不那么有用? - Julian Knight
显示剩余5条评论
25个回答

724

如果你正在使用Node.js,那么你肯定有EcmaScript 5,并且Date对象有一个toISOString方法。你需要对ISO8601进行轻微修改:

new Date().toISOString()
> '2012-11-04T14:51:06.157Z'

只需要删减一些内容,你就可以开始了:

new Date().toISOString().
  replace(/T/, ' ').      // replace T with a space
  replace(/\..+/, '')     // delete the dot and everything after
> '2012-11-04 14:55:45'

或者,简洁地说:new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '')

ISO8601必须使用UTC时间(第一个结果末尾的Z也表示这一点),因此默认情况下你会得到UTC时间(这总是件好事)。


4
聪明且简单的解决方案,避免使用任何库--不错! - Wingman4l7
14
如果你遇到了错误信息 "Object has no method 'toISOString'",那么你可能忘记使用 "new" 关键字。请注意添加 "new" 关键字以解决此问题。 - allenhwkim
61
需要注意的一点是,使用正则表达式进行这种操作速度较慢,而且在此处甚至不需要它们。以下代码可以正常工作:new Date().toISOString().replace('T', ' ').substr(0, 19) - klh
4
请注意,通过删除时区,现在它在每个具有不同偏移量的时区中表示不同的时间。 - RobG
2
改进答案:(new Date()).toISOString().slice(0,16).replace('T',' '),去掉了正则表达式。这样可以得到没有秒数的答案。 - Julian Knight
显示剩余5条评论

132

更新时间2021-10-06: 添加Day.js并删除@ashleedawg的无用编辑
更新时间2021-04-07: 添加了@Tampa提供的Luxon。
更新时间2021-02-28: 应该注意Moment.js不再被积极开发。它不会很快消失,因为它嵌入了很多其他东西。该网站提供了一些替代方案和解释。
更新时间2017-03-29: 添加了date-fns,并对Moment和Datejs做了一些备注
更新时间2016-09-14: 添加了SugarJS,它似乎有一些出色的日期/时间函数。


好吧,既然没有人真正提供实际的答案,那么这就是我的答案。

在标准化处理日期和时间时,使用库是最好的选择。在日期/时间计算中有很多边缘情况,因此将开发交给库是很有用的。

以下是主要与Node兼容的时间格式化库列表:

  • Day.js [于2021-10-06添加] "比Moment.js更快速,但使用相同的现代API,体积小只有2kB"
  • Luxon [于2017-03-29添加,感谢Tampa] "JavaScript日期和时间的强大、现代、友好的封装器。" - 从头开始重建了MomentJS,具有不可变类型、链式调用等特点。
  • Moment.js [感谢Mustafa] "一个轻量级(4.3k)的JavaScript日期库,用于解析、操作和格式化日期" - 包括国际化、计算和相对日期格式 - 更新于2017-03-29:现在不再那么轻量级了,但仍然是最全面的解决方案,尤其是如果您需要时区支持。 - 更新于2021-02-28:不再处于活跃开发状态。
  • date-fns [于2017-03-29添加,感谢Fractalf] 小巧、快速,适用于标准JS日期对象。如果您不需要时区支持,这是Moment的绝佳替代品。
  • SugarJS - 一个通用辅助库,为JavaScript内置对象类型添加了许多必要的功能。包括一些看起来很棒的日期/时间功能。
  • strftime - 就像它说的那样,简单明了
  • dateutil - 这是我在使用MomentJS之前使用的库
  • node-formatdate
  • TimeTraveller - "Time Traveller提供了一组用于处理日期的实用方法。从添加和减去到格式化。Time Traveller仅扩展它创建的日期对象,而不会污染全局命名空间。"
  • Tempus [感谢 Dan D] - 更新:此工具还可以与Node一起使用,并通过npm进行部署,请参阅文档

此外,还有非 Node 库:

  • Datejs [感谢 Peter Olson] - 无法在npm或GitHub中打包,因此不太适合在Node上使用 - 不推荐该库,因为它自2007年以来未更新!

2
这也非常相关 https://date-fns.org/ (https://github.com/date-fns/date-fns) - Fractalf
截至2018年2月,Moment团队正在进行名为Luxon的实验,网址为http://moment.github.io/luxon/index.html。 - alxndr
谢谢@alxndr,看起来是一个有用的重启。 - Julian Knight
Moment + toISOString() 在 RunKit 上的应用:https://runkit.com/shanekenyon87/5b845b0a64ab3f0012c9c607 - Shanerk

83

有一个用于转换的库:

npm install dateformat

然后写下您的要求:

var dateFormat = require('dateformat');

然后绑定该值:

var day=dateFormat(new Date(), "yyyy-mm-dd h:MM:ss");

请查看dateformat


2
它不支持CJS模块,无法在NextJS中运行。 - Emmanuel Meric de Bellefon
3
无法加载 ES 模块,请使用 import 进行加载。此错误信息来自于 internal/modules/cjs/loader.js 的第 1167 行,文件名为 filename,父路径为 parentPath,package.json 文件路径为 packageJsonPath。 - Unnikrishnan

52

我并不反对使用库。但在这种情况下,一个通用的库似乎过度了,除非应用程序的其他部分需要频繁处理日期。

编写此类小型实用程序函数对于初学者和有经验的程序员来说都是一种有用的练习,对于我们中的新手来说也可以是一次学习经历。

function dateFormat (date, fstr, utc) {
  utc = utc ? 'getUTC' : 'get';
  return fstr.replace (/%[YmdHMS]/g, function (m) {
    switch (m) {
    case '%Y': return date[utc + 'FullYear'] (); // no leading zeros required
    case '%m': m = 1 + date[utc + 'Month'] (); break;
    case '%d': m = date[utc + 'Date'] (); break;
    case '%H': m = date[utc + 'Hours'] (); break;
    case '%M': m = date[utc + 'Minutes'] (); break;
    case '%S': m = date[utc + 'Seconds'] (); break;
    default: return m.slice (1); // unknown code, remove %
    }
    // add leading zero if required
    return ('0' + m).slice (-2);
  });
}

/* dateFormat (new Date (), "%Y-%m-%d %H:%M:%S", true) returns 
   "2012-05-18 05:37:21"  */

37
虽然这种方法确实有助于学习,但我不同意这比使用小型、精心构建的库更好的结论。一个库会被维护,并且更有可能涵盖设计中的边缘情况,这些情况可能一开始对你来说并不明显,但在某些时候可能会轻松地导致问题-由于其固有复杂性,日期/时间计算特别容易出现这些问题。 - Julian Knight
8
这是使用String.replace()方法的很好示例,创意加一分。 - JamieJag
7
在这种情况下,一定要使用库。格式可能会改变。即使它没有改变,这也会增加代码的复杂性。维护你的代码的其他人将不得不花时间去理解这个函数并确保它是正确的。练习是为了学校;问题是关于实际应用。当然,如果这是你第一次或第二次“真正”的项目,那么做这样的事情可能是有益的,这样你就可以学习为什么不应该这样做。 - Sergey Orshanskiy
4
我理解你的意思是赞同使用经过验证/经受考验的库的普遍观点,但它们也可能增加部署复杂性。该代码将所有与日历相关的细节委托给底层的日期对象,并在适当的位置调用例如getUTCDate()方法。此外,如果有人发现这个代码中存在错误,他们可以在stackoverflow.com上报告它,从而与任何其他库的多眼睛/浅层错误方面相匹配。+1 - steamer25

28

请检查下面的代码和链接:Date对象Intl.DateTimeFormat

// var ts_hms = new Date(UTC);
// ts_hms.format("%Y-%m-%d %H:%M:%S")

// exact format
console.log(new Date().toISOString().replace('T', ' ').substring(0, 19))

// other formats
console.log(new Date().toUTCString())
console.log(new Date().toLocaleString('en-US'))
console.log(new Date().toString())

// log format
const parts = new Date().toString().split(' ')
console.log([parts[1], parts[2], parts[4]].join(' '))

// intl
console.log(new Intl.DateTimeFormat('en-US', {dateStyle: 'long', timeStyle: 'long'}).format(new Date()))


更新:添加日志格式 - dreamLo

17

不使用任何库,以易于阅读和定制的方式获取所需格式的时间戳:

function timestamp(){
  function pad(n) {return n<10 ? "0"+n : n}
  d=new Date()
  dash="-"
  colon=":"
  return d.getFullYear()+dash+
  pad(d.getMonth()+1)+dash+
  pad(d.getDate())+" "+
  pad(d.getHours())+colon+
  pad(d.getMinutes())+colon+
  pad(d.getSeconds())
}

(如果你需要以UTC格式显示时间,只需更改函数调用。例如,“getMonth”变为“getUTCMonth”)


13

JavaScript库sugar.js(http://sugarjs.com/)具有格式化日期的功能。

示例:

Date.create().format('{dd}/{MM}/{yyyy} {hh}:{mm}:{ss}.{fff}')

4
看起来是一本非常棒的图书馆。他们的格式相当流畅,他们的文档展示了我在 JavaScript 中已经感到沮丧的许多其他问题的优雅解决方案。打算试一试。 - eimajenthat
今天早上刚试了一下,看起来非常不错,很开心能用它。 - klewis

9
我正在使用 dateformat 在Nodejs和angularjs中,非常好用。
安装
$ npm install dateformat
$ dateformat --help

演示

var dateFormat = require('dateformat');
var now = new Date();

// Basic usage
dateFormat(now, "dddd, mmmm dS, yyyy, h:MM:ss TT");
// Saturday, June 9th, 2007, 5:46:21 PM

// You can use one of several named masks
dateFormat(now, "isoDateTime");
// 2007-06-09T17:46:21

// ...Or add your own
dateFormat.masks.hammerTime = 'HH:MM! "Can\'t touch this!"';
dateFormat(now, "hammerTime");
// 17:46! Can't touch this!

// You can also provide the date as a string
dateFormat("Jun 9 2007", "fullDate");
// Saturday, June 9, 2007
...

8
使用 Date 对象提供的方法,如下所示:
var ts_hms = new Date();

console.log(
    ts_hms.getFullYear() + '-' + 
    ("0" + (ts_hms.getMonth() + 1)).slice(-2) + '-' + 
    ("0" + (ts_hms.getDate())).slice(-2) + ' ' +
    ("0" + ts_hms.getHours()).slice(-2) + ':' +
    ("0" + ts_hms.getMinutes()).slice(-2) + ':' +
    ("0" + ts_hms.getSeconds()).slice(-2));

这看起来很杂乱,但使用JavaScript核心方法应该可以正常工作。


2
我同意你需要在getMonth()上加1,因为一月返回的是0,但我不认为你想要在getDate()上加1。 - Steve Onorato

7

日期格式化最简单的方法是使用moment库。https://momentjs.com/

const moment = require('moment')
const current = moment().utc().format('Y-M-D H:M:S')

1
谢谢,@Jazeb_007,这对我有用,即使我不需要 toISOString()toUTCString() - Bablu Ahmed
1
moment.js从现在开始将只处于维护模式 https://momentjs.com/docs/#/-project-status/ 请使用Date。 - Indra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接