我注意到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()对象支持的格式说明符的文档在哪里?


当前回答

在JavaScript中格式化,尤其是解析日期可能有点头疼。并非所有浏览器都以相同的方式处理日期。因此,虽然了解基本方法很有用,但使用助手库更实用。

Adam Shaw的XDate javascript库自2011年年中就已经问世,目前仍在积极开发中。它有很棒的文档,很棒的API,格式化,试图保持向后兼容,甚至支持本地化字符串。

更改区域设置字符串的链接:https://gist.github.com/1221376

其他回答

简短的回答

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

虽然JavaScript为您提供了许多格式化和计算的好方法,但我更喜欢在应用程序开发期间使用Moment.js(momentjs.com)库,因为它非常直观,节省了大量时间。

尽管如此,我建议大家也学习一下基本的JavaScript API,以便更好地理解。

确保在JavaScript中处理日期时签出Datejs。正如您在toString函数的例子中看到的那样,它非常令人印象深刻,并且有很好的文档记录。

编辑:Tyler Forsyth指出,datejs已经过时了。我在当前的项目中使用了它,并没有遇到任何问题,但您应该意识到这一点,并考虑其他选择。

无框架,有限但重量轻

var d = (new Date()+'').split(' ');
// ["Tue", "Sep", "03", "2013", "21:54:52", "GMT-0500", "(Central", "Daylight", "Time)"]

[d[3], d[1], d[2], d[4]].join(' ');
// "2013 Sep 03 21:58:03"

只是为了继续龚志涛的坚定回答-这处理上午/下午

 Date.prototype.format = function (format) //author: meizz
{
    var hours = this.getHours();
    var ttime = "AM";
    if(format.indexOf("t") > -1 && hours > 12)
    {
        hours = hours - 12;
        ttime = "PM";
     }

var o = {
    "M+": this.getMonth() + 1, //month
    "d+": this.getDate(),    //day
    "h+": hours,   //hour
    "m+": this.getMinutes(), //minute
    "s+": this.getSeconds(), //second
    "q+": Math.floor((this.getMonth() + 3) / 3),  //quarter
    "S": this.getMilliseconds(), //millisecond,
    "t+": ttime
}

if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
  (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) if (new RegExp("(" + k + ")").test(format))
    format = format.replace(RegExp.$1,
      RegExp.$1.length == 1 ? o[k] :
        ("00" + o[k]).substr(("" + o[k]).length));
return format;
}