在哪里可以找到有关在 JavaScript 中格式化日期的文档?

我注意到 JavaScript 的new 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“使用日期” 格式化时间和日期的 10 种方法

基本上,您有三种方法,必须自己组合字符串:

getDate() // Returns the date
getMonth() // Returns the month
getFullYear() // Returns the year

例:

var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1; //Months are zero based
var curr_year = d.getFullYear();
console.log(curr_date + "-" + curr_month + "-" + curr_year);

Moment.js

它是一个(轻量级)* JavaScript 日期库,用于解析,处理和格式化日期。

var a = moment([2010, 1, 14, 15, 25, 50, 125]);
a.format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
a.format("ddd, hA");                       // "Sun, 3PM"

(*)轻巧,意味着在最小的设置中缩小了 9.3KB 并压缩了文件(2014 年 2 月)

如果您已经在项目中使用jQuery UI ,则可以使用内置的 datepicker 方法来格式化日期对象:

$.datepicker.formatDate('yy-mm-dd', new Date(2007, 1 - 1, 26));

但是,日期选择器仅格式化日期,而不能格式化时间。

看一下jQuery UI datepicker formatDate的示例。

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

我今天偶然发现了这个问题,很惊讶没有人花时间回答这个简单的问题。的确,那里有许多库可以帮助您进行日期操作。有些比其他更好。但这不是问的问题。

AFAIK,纯 JavaScript 不支持指定要使用的格式说明符。但是它确实支持格式化日期和 / 或时间的方法,例如.toLocaleDateString() .toLocaleTimeString().toUTCString()

我最常使用的Date对象引用位于w3schools.com 网站上 (但Google 的快速搜索将显示更多可以更好地满足您的需求的对象)。

还要注意,“ 日期对象属性”部分提供了指向prototype的链接,该链接说明了使用自定义方法扩展 Date 对象的一些方法。多年来,JavaScript 社区一直在争论这是否是最佳做法,我并不主张或反对它,只是指出它的存在。

自定义格式功能:

对于固定格式,只需一个简单的功能即可完成。以下示例生成国际格式 YYYY-MM-DD:

function dateToYMD(date) {
    var d = date.getDate();
    var m = date.getMonth() + 1;
    var y = date.getFullYear();
    return '' + y + '-' + (m<=9 ? '0' + m : m) + '-' + (d <= 9 ? '0' + d : d);
}

注意:但是,扩展 Javascript 标准库通常不是一个好主意(例如,通过将此函数添加到 Date 的原型中)。

更高级的功能可以根据格式参数生成可配置的输出。在同一页面上有几个很好的例子。

如果编写格式化函数的时间太长,那么周围有很多函数库。其他一些答案已经列举出来了。但是,越来越多的依赖关系也与之相反。

标准 ECMAScript 格式化功能:

由于 ECMAscript 是最新版本,因此Date类具有一些特定的格式化功能:

toDateString :与实现有关,仅显示日期。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.todatestring

new Date().toDateString(); // e.g. "Fri Nov 11 2016"

toISOString :显示 ISO 8601 日期和时间。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.toisostring

new Date().toISOString(); // e.g. "2016-11-21T08:00:00.000Z"

toJSON :JSON 的字符串化器。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tojson

new Date().toJSON(); // e.g. "2016-11-21T08:00:00.000Z"

toLocaleDateString :与实现有关,以区域设置格式显示日期。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tolocaledatestring

new Date().toLocaleDateString(); // e.g. "21/11/2016"

toLocaleString :与实现有关,日期和时间为区域设置格式。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tolocalestring

new Date().toLocaleString(); // e.g. "21/11/2016, 08:00:00 AM"

toLocaleTimeString :与实现有关,以语言环境格式表示。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tolocaletimestring

new Date().toLocaleTimeString(); // e.g. "08:00:00 AM"

toString :日期的通用 toString。

http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tostring

new Date().toString(); // e.g. "Fri Nov 11 2016 08:00:00 GMT+0100 (W. Europe Standard Time)"

注意:可以从这些格式函数中生成自定义输出:

new Date().toISOString().slice(0,10); // By @Image72, return YYYY-MM-DD

简短答案

没有 javascript 可以满足的 “通用” 文档。每个具有 javascript 的浏览器实际上都是一种实现。但是,大多数现代浏览器都倾向于遵循一个标准,那就是 EMCAScript 标准。 ECMAScript 标准字符串至少需要采用 ISO 8601 定义的修改实现。

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

由此,您可以期待基本功能,但是 “应该” 本质上不是 “是”。不过,我将在此过程中进行更深入的介绍,因为似乎只有三个人实际回答了这个问题(即 Scott,goofballLogic 和 peller),对我来说,这表明大多数人都不知道当您出现时实际发生了什么创建一个 Date 对象。


长答案

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


要回答该问题,或者通常甚至寻找该问题的答案,您需要知道 javascript 不是一种新颖的语言。它实际上是 ECMAScript 的实现,并且遵循 ECMAScript 标准(但请注意,javascript 实际上也早于这些标准; EMCAScript 标准是在 LiveScript / JavaScript 的早期实现基础上构建的)。当前的 ECMAScript 标准为 5.1(2011);在最初提出问题时('09 年 6 月),标准是 3(放弃了 4),但在 2009 年底该职位发布后不久发布了 5。 javascript 实现可能遵循的标准,可能无法反映实际的标准,因为 a)它是给定标准的实现,b)并非该标准的所有实现都是纯净的,并且 c)功能未与 a 同步发布 d)新标准的实施是一项持续不断的工作

本质上,在处理 javascript 时,您正在处理实现(JavaScript 本身)的派生类(特定于浏览器的 javascript)。以 Google 的 V8 为例,它实现了 ECMAScript 5.0,但是 Internet Explorer 的 JScript 并未尝试遵循任何 ECMAScript 标准,而 Internet Explorer 9 却遵循了 ECMAScript 5.0。

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

new Date(value)

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

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


这两个函数应该看起来很熟悉,但这并不能立即回答您的问题,量化为可接受的 “日期格式” 的内容需要进一步说明。当您将字符串传递给 new Date()时,它将调用原型(请注意,我宽松地使用了原型一词;版本可能是单个函数,或者可能是单个函数中条件语句的一部分)您的字符串作为 “value” 参数的参数的新 Date(value) 。此函数将首先检查它是数字还是字符串。可以在以下位置找到此功能的文档:

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 函数。但是,请注意,“年” 不是实际的年,仅是对 “年” 参数的引用。

Google 的 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,dateparser-inl.h,DateParser :: Parse

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

该函数实际上定义了它接受的格式。本质上,它将检查 EMCAScript 5.0 ISO 8601 标准,如果不符合标准,则它将尝试根据旧格式来构建日期。基于评论的一些要点:

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

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

http://tools.ietf.org/html/rfc2822#page-14

Microsoft 开发人员网络还提到了 Date 对象的另一个标准:ECMA-402,ECMAScript 国际化 API 规范,它是对 ECMAScript 5.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.2

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

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

http://tools.ietf.org/html/rfc2822#page-14

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

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

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

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

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

资源资源

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date

http://msdn.microsoft.com/zh-CN/library/ff743760(v=vs.94).aspx

确保在 JavaScript 中处理日期时签出Datejs 。在toString 函数的情况下,它令人印象深刻且有据可查。

编辑 :泰勒 · 福赛斯指出,datejs 已过时。我在当前项目中使用了它,但没有任何问题,但是您应该意识到这一点并考虑替代方法。

您可以使用meizz指出的新format方法来扩展Date对象,以下是作者提供的代码。这是一个jsfiddle

Date.prototype.format = function(format) //author: meizz
{
  var o = {
    "M+" : this.getMonth()+1, //month
    "d+" : this.getDate(),    //day
    "h+" : this.getHours(),   //hour
    "m+" : this.getMinutes(), //minute
    "s+" : this.getSeconds(), //second
    "q+" : Math.floor((this.getMonth()+3)/3),  //quarter
    "S" : this.getMilliseconds() //millisecond
  }

  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;
}

alert(new Date().format("yyyy-MM-dd"));
alert(new Date("january 12 2008 11:12:30").format("yyyy-MM-dd h:mm:ss"));

您引用的功能不是标准 Javascript,不太可能跨浏览器移植,因此不是很好的做法。 ECMAScript 3 规范保留了解析和输出格式功能,直到 Javascript 实现为止。 ECMAScript 5添加了 ISO8601 支持的子集。我相信您提到的 toString()函数是一种浏览器(Mozilla?)的创新。

一些库提供了用于对此进行参数化的例程,其中一些具有广泛的本地化支持。您也可以在dojo.date.locale 中检出方法。

我制作了一个非常简单的格式化程序,它是 cut / n / pastable(已更新为更整洁的版本):

function DateFmt(fstr) {
  this.formatString = fstr

  var mthNames = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  var dayNames = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
  var zeroPad = function(number) {
     return ("0"+number).substr(-2,2);
  }

  var dateMarkers = {
    d:['getDate',function(v) { return zeroPad(v)}],
    m:['getMonth',function(v) { return zeroPad(v+1)}],
    n:['getMonth',function(v) { return mthNames[v]; }],
    w:['getDay',function(v) { return dayNames[v]; }],
    y:['getFullYear'],
    H:['getHours',function(v) { return zeroPad(v)}],
    M:['getMinutes',function(v) { return zeroPad(v)}],
    S:['getSeconds',function(v) { return zeroPad(v)}],
    i:['toISOString']
  };

  this.format = function(date) {
    var dateTxt = this.formatString.replace(/%(.)/g, function(m, p) {
      var rv = date[(dateMarkers[p])[0]]()

      if ( dateMarkers[p][1] != null ) rv = dateMarkers[p][1](rv)

      return rv

    });

    return dateTxt
  }

}

fmt = new DateFmt("%w %d:%n:%y - %H:%M:%S  %i")
v = fmt.format(new Date())

http://snipplr.com/view/66968.82825/