我注意到JavaScript的新Date()函数在接受多种格式的日期方面非常聪明。

Xmas95 = new Date("25 Dec, 1995 23:15:00")
Xmas95 = new Date("2009 06 12,12:52:39")
Xmas95 = new Date("20 09 2006,12:52:39")

调用new Date()函数时,我在任何地方都找不到显示所有有效字符串格式的文档。

这用于将字符串转换为日期。如果我们从相反的方面来看,即将日期对象转换为字符串,直到现在,我的印象是JavaScript没有将日期对象格式化为字符串的内置API。

编者按:以下方法是询问者在特定浏览器上的尝试,但通常不起作用;请参阅本页上的答案以了解一些实际解决方案。

今天,我在date对象上使用了toString()方法,令人惊讶的是,它可以将日期格式化为字符串。

var d1 = new Date();
d1.toString('yyyy-MM-dd');       //Returns "2009-06-29" in Internet Explorer, but not Firefox or Chrome
d1.toString('dddd, MMMM ,yyyy')  //Returns "Monday, June 29,2009" in Internet Explorer, but not Firefox or Chrome

在这里,我也找不到任何关于将日期对象格式化为字符串的方法的文档。

列出Date()对象支持的格式说明符的文档在哪里?


当前回答

只是另一个选项,我写道:

DP_DateExtensions库

不确定它是否有用,但我发现它在几个项目中都很有用——看起来它可以满足您的需要。

支持日期/时间格式、日期数学(添加/减去日期部分)、日期比较、日期解析等。

如果你已经在使用一个框架(他们都有能力),没有理由考虑这个问题,但如果你只需要在项目中快速添加日期操作,那就给它一个机会。

其他回答

许多框架(您可能已经在使用)具有您可能不知道的日期格式。jQueryUI已经被提及,但其他框架如Kendo UI(全球化)、Yahoo UI(Util)和AngularJS也有。

// 11/6/2000
kendo.toString(new Date(value), "d")

// Monday, November 06, 2000
kendo.toString(new Date(2000, 10, 6), "D")

简短的回答

javascript没有“通用”文档;每一个使用javascript的浏览器都是真正的实现。然而,大多数现代浏览器都倾向于遵循一个标准,那就是EMCAScript标准;ECMAScript标准字符串将至少采用ISO 8601定义的修改实现。

除此之外,IETF还提出了浏览器倾向于遵循的第二个标准,即RFC 2822中对时间戳的定义。实际文档可以在底部的参考列表中找到。

从这一点上,你可以期待基本的功能,但“应该”是什么并不本质上是什么。不过,我将从程序上对此进行深入探讨,因为似乎只有三个人真正回答了这个问题(即斯科特、高飞逻辑和佩勒),对我来说,这意味着大多数人不知道创建Date对象时实际发生了什么。


答案很长

列出Date()对象支持的格式说明符的文档在哪里?


要回答这个问题,或者通常甚至寻找这个问题的答案,您需要知道javascript不是一种新颖的语言;它实际上是ECMAScript的实现,遵循ECMAScript标准(但注意,javascript实际上也早于这些标准;EMCAScript标准是基于LiveScript/javascript的早期实现)。当前ECMAScript标准为5.1(2011);在最初提出这个问题的时候(2009年6月),标准是3(4被放弃),但在2009年底帖子发布后不久发布了5。这应该概述一个问题;javascript实现可能遵循的标准可能无法反映实际存在的内容,因为a)它是给定标准的实现,b)不是所有标准的实现都是纯粹的,c)功能没有与新标准同步发布,因为d)实现是一项持续的工作

本质上,在处理javascript时,您要处理的是一个实现(javascript本身)的派生(特定于浏览器的javascript)。例如,Google的V8实现了ECMAScript 5.0,但Internet Explorer的JScript不试图符合任何ECMAScript标准,而Internet Explorer 9确实符合ECMAScript5.0。

当一个参数传递给new Date()时,它将强制转换此函数原型:

new Date(value)

当两个或多个参数传递给new Date()时,它将强制转换此函数原型:

new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )

Both of those functions should look familiar, but this does not immediately answer your question and what quantifies as an acceptable “date format” requires further explanation. When you pass a string to new Date(), it will call the prototype (note that I'm using the word

原型

loosely; the versions may be individual functions, or it may be part of a conditional statement in a single function) for

新日期(值)

with your string as the argument for the “value” parameter. This function will first check whether it is a number or a string. The documentation for this function can be found here:

http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.3.2

由此,我们可以推断,为了获得新Date(value)所允许的字符串格式,我们必须查看方法Date.parse(string)。该方法的文档可以在这里找到:

http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.4.2

我们还可以进一步推断,日期应采用修改后的ISO 8601扩展格式,如下所示:

http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15

然而,我们可以从经验中认识到,javascript的Date对象接受其他格式(首先是因为存在这个问题),这是可以的,因为ECMAScript允许特定于实现的格式。然而,这仍然不能回答可用格式上有哪些文档,也不能回答实际允许的格式。我们将研究Google的javascript实现V8;请注意,我并不是说这是“最佳”javascript引擎(如何定义“最佳”甚至“良好”),我们不能假设V8中允许的格式代表了当今可用的所有格式,但我认为可以合理地假设它们确实符合现代期望。

Google的V8,date.js,DateConstructor

https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#141

查看DateConstructor函数,我们可以推断出我们需要找到DateParse函数;但是,请注意,“year”不是实际的年份,只是对“year“参数的引用。

谷歌的V8,date.js,DateParse

https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#270

这将调用%DateParseString,它实际上是C++函数的运行时函数引用。指以下代码:

Google的V8,runtime.cc,%DateParseString

https://code.google.com/p/v8/source/browse/trunk/src/runtime.cc?r=18400#9559

我们在这个函数中关注的函数调用是用于DateParser::Parse();忽略这些函数调用周围的逻辑,这些只是检查是否符合编码类型(ASCII和UC16)。DateParser::此处定义了Parse:

Google的V8,日期解析器inl.h,日期解析器::Parse

https://code.google.com/p/v8/source/browse/trunk/src/dateparser-inl.h?r=18400#36

这是一个函数,它实际定义了它接受的格式。本质上,它检查EMCAScript 5.0 ISO 8601标准,如果它不符合标准,那么它将尝试基于传统格式构建日期。基于评论的几个要点:

解析器不知道的第一个数字之前的单词将被忽略。带圆括号的文本将被忽略。后跟“:”的无符号数字被解释为“时间分量”。后跟“.”的无符号数字被解释为“时间分量”,并且必须后跟毫秒。带符号的数字后跟小时或小时分钟(例如+5:15或+0515)被解释为时区。声明小时和分钟时,可以使用“hh:mm”或“hhmm”。表示时区的单词被解释为时区。所有其他数字都被解释为“日期成分”。所有以月份前三位数字开头的单词都被解释为月份。您可以使用以下两种格式之一同时定义分钟和小时:“hh:mm”或“hhmm”。处理数字后,不允许使用“+”、“-”和不匹配的“)”等符号。匹配多种格式(例如1970-01-01)的项目将作为符合标准的EMCAScript 5.0 ISO 8601字符串处理。

因此,这应该足以让您基本了解在将字符串传递到Date对象时会发生什么。您可以通过查看Mozilla在Mozilla开发者网络上指向的以下规范(符合IETF RFC 2822时间戳)来进一步扩展这一点:

https://www.rfc-editor.org/rfc/rfc2822#page-14

Microsoft开发者网络还提到了Date对象的一个附加标准:ECMA-402,即ECMAScript国际化API规范,它是对ECMAScript5.1标准(以及将来的标准)的补充。可以在这里找到:

http://www.ecma-international.org/ecma-402/1.0/

在任何情况下,这都应该有助于强调,没有普遍表示javascript所有实现的“文档”,但仍有足够的文档可用于合理理解Date对象可接受的字符串。当你想起来的时候,这是一个很沉重的问题,是吗P

工具书类http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.3.2http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.4.2http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15https://www.rfc-editor.org/rfc/rfc2822#page-14http://www.ecma-international.org/ecma-402/1.0/https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#141https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#270https://code.google.com/p/v8/source/browse/trunk/src/runtime.cc?r=18400#9559https://code.google.com/p/v8/source/browse/trunk/src/dateparser-inl.h?r=18400#36资源https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Datehttp://msdn.microsoft.com/en-us/library/ff743760(v=vs.94).aspx

在浏览了其他答案中提供的几个选项后,我决定编写自己的有限但简单的解决方案,其他人可能也会觉得有用。

/**
* Format date as a string
* @param date - a date object (usually "new Date();")
* @param format - a string format, eg. "DD-MM-YYYY"
*/
function dateFormat(date, format) {
    // Calculate date parts and replace instances in format string accordingly
    format = format.replace("DD", (date.getDate() < 10 ? '0' : '') + date.getDate()); // Pad with '0' if needed
    format = format.replace("MM", (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1)); // Months are zero-based
    format = format.replace("YYYY", date.getFullYear());
    return format;
}

示例用法:

console.log("The date is: " + dateFormat(new Date(), "DD/MM/YYYY"));

对于好奇的人来说,有一个名为tc39/temporal的实验特性,目前正处于第3阶段,它为ECMAScript语言带来了一个现代的日期/时间API。

引用tc39网站:

日期一直是ECMAScript中的一个长期难点。这是对Temporal的建议,它是一个充当顶级命名空间(如Math)的全局对象,为ECMAScript语言带来了现代的日期/时间API。要详细了解Date的一些问题以及Temporal的动机,请参阅:Fixing JavaScript Date。

这里有一本烹饪书,可以帮助您开始学习Temporal的来龙去脉。

其他资源:

GitHub存储库-tc39/临时提案YouTube上还有一段视频,详细介绍了这一提议。本文对上述视频进行了简要概述-了解JavaScript如何使用提案时间推进DateTime如何超越时间:使用时态构建未来JavaScript应用程序

如果您希望只显示两位数的时间,这可能会帮助您:

var now = new Date();
var cHour = now.getHours();
var cMinuts = now.getMinutes();
var cSeconds = now.getSeconds();

var outStr = (cHour <= 0 ? ('0' + cHour) : cHour) + ':' + (cMinuts <= 9 ? ('0' + cMinuts) : cMinuts) + ':' + (cSeconds <= 9 ? '0' + cSeconds : cSeconds);