我注意到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来将日期对象格式化为字符串。
编者注:以下方法是提问者尝试在特定浏览器上工作但一般不起作用;请参阅此页面上的答案以查看一些实际解决方案。
今天,我在日期对象上使用了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()
对象支持的格式说明符的文档在哪里?
我喜欢10 ways to format time and date using JavaScript和Working with Dates。
基本上,你有三种方法,你必须自己组合字符串:
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);
我制作了这个非常简单的格式化程序,它是cut / n / pastable(更新为neater版本):
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())
框架免费,有限但轻松
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"
DateJS肯定是全功能的,但我推荐this MUCH simpler lib (JavaScript Date Format),我更喜欢它只是因为它只有120行左右。
通过查看其他答案中提供的几个选项,我决定编写自己有限但简单的解决方案,其他人也可能觉得有用。
/**
* 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"));
这是我经常使用的一个功能。结果是yyyy-mm-dd hh:mm:ss.nnn。
function date_and_time() {
var date = new Date();
//zero-pad a single zero if needed
var zp = function (val){
return (val <= 9 ? '0' + val : '' + val);
}
//zero-pad up to two zeroes if needed
var zp2 = function(val){
return val <= 99? (val <=9? '00' + val : '0' + val) : ('' + val ) ;
}
var d = date.getDate();
var m = date.getMonth() + 1;
var y = date.getFullYear();
var h = date.getHours();
var min = date.getMinutes();
var s = date.getSeconds();
var ms = date.getMilliseconds();
return '' + y + '-' + zp(m) + '-' + zp(d) + ' ' + zp(h) + ':' + zp(min) + ':' + zp(s) + '.' + zp2(ms);
}
您可能会发现日期对象的这种修改很有用,它比任何库都小,并且可以轻松扩展以支持不同的格式:
注意:
码
Date.prototype.format = function(format) {
// set default format if function argument not provided
format = format || 'YYYY-MM-DD hh:mm';
var zeropad = function(number, length) {
number = number.toString();
length = length || 2;
while(number.length < length)
number = '0' + number;
return number;
},
// here you can define your formats
formats = {
YYYY: this.getFullYear(),
MM: zeropad(this.getMonth() + 1),
DD: zeropad(this.getDate()),
hh: zeropad(this.getHours()),
mm: zeropad(this.getMinutes())
},
pattern = '(' + Object.keys(formats).join(')|(') + ')';
return format.replace(new RegExp(pattern, 'g'), function(match) {
return formats[match];
});
};
使用
var now = new Date;
console.log(now.format());
// outputs: 2015-02-09 11:47
var yesterday = new Date('2015-02-08');
console.log(yesterday.format('hh:mm YYYY/MM/DD'));
// outputs: 00:00 2015/02/08
只是为了继续gongzhitaao的坚实答案 - 这处理上午/下午
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;
}
我无法找到有关有效日期格式的任何权威文档,因此我编写了自己的测试以查看各种浏览器支持的内容。
http://blarg.co.uk/blog/javascript-date-formats
我的结果总结了以下格式在我测试的所有浏览器中都有效(示例使用日期“2013年8月9日”):
[全年] / [月] / [日期编号] - 月份可以是带或不带前导零的数字,也可以是短格式或长格式的月份名称,日期编号可以带或不带前导零。
[月] / [全年] / [日期编号] - 月份可以是带或不带前导零的数字,也可以是短格式或长格式的月份名称,日期编号可以带或不带前导零。
[全年],[月份名称]和[日期编号]的任意组合用空格分隔 - 月份名称可以是短格式或长格式,日期编号可以带或不带前导零。
也适用于“现代浏览器”(或者换句话说除了IE9及以下版本的所有浏览器)
[全年] - [月份编号] - [日期编号] - 月份和日期编号必须包含前导零(这是MySQL Date type使用的格式)
使用月份名称: 有趣的是,当使用月份名称时,我发现只使用月份名称的前3个字符,所以以下所有内容都是完全有效的:
new Date('9 August 2013');
new Date('9 Aug 2013');
new Date('9 Augu 2013');
new Date('9 Augustagfsdgsd 2013');
在JavaScript中格式化,特别是解析日期可能有点令人头疼。并非所有浏览器都以相同的方式处理日期。因此,虽然了解基本方法很有用,但使用辅助库更实用。
XDate javascript library的Adam Shaw自2011年年中以来一直存在,并且仍处于积极发展阶段。它具有出色的文档,出色的API,格式化,尝试保持向后兼容,甚至支持本地化字符串。
链接到更改区域设置字符串:https://gist.github.com/1221376
示例代码:
var d = new Date();
var time = d.toISOString().replace(/.*?T(\d+:\d+:\d+).*/, "$1");
输出:
"13:45:20"
它是一个(轻量级)* 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月)
库sugar.js具有一些用于处理JavaScript日期的强大功能。它是非常好的documented。
Sugar为Date类提供了很多热爱,从Date.create方法开始,该方法可以理解15种主要语言中的任何格式的日期,包括“1小时前”等相对格式。日期也可以使用易于理解的语法以任何格式或语言输出,并使用常用日期格式的快捷方式。复杂的日期比较也可以使用像is这样的方法,它可以理解任何格式并应用内置的精度。
几个例子:
Date.create('July 4, 1776') -> July 4, 1776
Date.create(-446806800000) -> November 5, 1955
Date.create(1776, 6, 4) -> July 4, 1776
Date.create('1776年07月04日', 'ja') -> July 4, 1776
Date.utc.create('July 4, 1776', 'en') -> July 4, 1776
Date.create().format('{Weekday} {d} {Month}, {yyyy}') -> Monday July 4, 2003
Date.create().format('{hh}:{mm}') -> 15:57
Date.create().format('{12hr}:{mm}{tt}') -> 3:57pm
Date.create().format(Date.ISO8601_DATETIME) -> 2011-07-05 12:24:55.528Z
Date.create().is('the 7th of June') -> false
Date.create().addMonths(2); ->"Sunday, June 15, 2014 13:39"
使用您正在使用的源格式格式化日期的最可靠方法是应用以下步骤:
new Date()
创建一个Date
对象.getDate()
,.getMonth()
和.getFullYear()
分别获得日,月和年示例:
var date = '2015-11-09T10:46:15.097Z';
function format(input) {
var date = new Date(input);
return [
("0" + date.getDate()).slice(-2),
("0" + (date.getMonth()+1)).slice(-2),
date.getFullYear()
].join('/');
}
document.body.innerHTML = format(date); // OUTPUT : 09/11/2015
(另见this Fiddle)。
您还可以使用内置的.toLocaleDateString
方法为您进行格式化。您只需要传递适当的区域设置和选项以匹配正确的格式,但遗憾的是,只有现代浏览器支持(*):
var date = '2015-11-09T10:46:15.097Z';
function format(input) {
return new Date(input).toLocaleDateString('en-GB', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
}
document.body.innerHTML = format(date); // OUTPUT : 09/11/2015
(另见this Fiddle)。
(*)According to the MDN,“现代浏览器”指Chrome 24 +,Firefox 29 +,IE11,Edge12 +,Opera 15+和Safari nightly build
只是另一个选项,我写道:
不确定它是否有帮助,但我发现它在几个项目中很有用 - 看起来它会做你需要的。
支持日期/时间格式,日期数学(加/减日期部分),日期比较,日期解析等。它是自由开源的。
没有理由考虑它,如果你已经在使用一个框架(他们都有能力),但如果你只需要快速添加日期操作到项目给它一个机会。
格式化日期以返回“2012-12-29”的正确方法是使用JavaScript Date Format的脚本:
var d1 = new Date();
return d1.format("dd-m-yy");
此代码不起作用:
var d1 = new Date();
d1.toString('yyyy-MM-dd');
如果您只想显示两位数的时间,这可能会对您有所帮助:
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);
使用这个功能
toTimeString() and toLocaleDateString()
有关详细信息,请参阅以下链接https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
JsSimpleDateFormat是一个库,可以格式化日期对象并将格式化的字符串解析回Date对象。它使用Java格式(SimpleDateFormat类)。月份和日期的名称可以本地化。
例:
var sdf = new JsSimpleDateFormat("EEEE, MMMM dd, yyyy");
var formattedString = sdf.format(new Date());
var dateObject = sdf.parse("Monday, June 29, 2009");
答案是“无处”,因为日期格式是专有功能。我不认为toString函数旨在符合特定格式。例如在ECMAScript 5.1规范(http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf,2013年2月8日,第173页)中,toString函数记录如下:
“字符串的内容依赖于实现”
下面的示例等函数可用于轻松完成格式化。
function pad(toPad, padWith) {
return (String(padWith) + String(toPad)).slice(-1 * padWith.length);
}
function dateAsInputValue(toFormat) {
if(!(toFormat instanceof Date)) return null;
return toFormat.getFullYear() + "-" + pad(toFormat.getMonth() + 1, "00") + "-" + pad(toFormat.getDate(), "00");
}
function timeAsInputValue(toFormat) {
if(!(toFormat instanceof Date)) return null;
return pad(toFormat.getHours(), "00") + ":" + pad(toFormat.getMinutes(), "00") + ":" + pad(toFormat.getSeconds(), "00");
}
如果您不需要像Moment.js这样的库提供的所有功能,那么您可以使用我的strftime端口。它的重量轻(1.35 KB与57.9 KB缩小相比,Moment.js 2.15.0),并提供了strftime()
的大部分功能。
/* Port of strftime(). Compatibility notes:
*
* %c - formatted string is slightly different
* %D - not implemented (use "%m/%d/%y" or "%d/%m/%y")
* %e - space is not added
* %E - not implemented
* %h - not implemented (use "%b")
* %k - space is not added
* %n - not implemented (use "\n")
* %O - not implemented
* %r - not implemented (use "%I:%M:%S %p")
* %R - not implemented (use "%H:%M")
* %t - not implemented (use "\t")
* %T - not implemented (use "%H:%M:%S")
* %U - not implemented
* %W - not implemented
* %+ - not implemented
* %% - not implemented (use "%")
*
* strftime() reference:
* http://man7.org/linux/man-pages/man3/strftime.3.html
*
* Day of year (%j) code based on Joe Orost's answer:
* http://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366
*
* Week number (%V) code based on Taco van den Broek's prototype:
* http://techblog.procurios.nl/k/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html
*/
function strftime(sFormat, date) {
if (!(date instanceof Date)) date = new Date();
var nDay = date.getDay(),
nDate = date.getDate(),
nMonth = date.getMonth(),
nYear = date.getFullYear(),
nHour = date.getHours(),
aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
isLeapYear = function() {
if (nYear&3!==0) return false;
return nYear%100!==0 || year%400===0;
},
getThursday = function() {
var target = new Date(date);
target.setDate(nDate - ((nDay+6)%7) + 3);
return target;
},
zeroPad = function(nNum, nPad) {
return ('' + (Math.pow(10, nPad) + nNum)).slice(1);
};
return sFormat.replace(/%[a-z]/gi, function(sMatch) {
return {
'%a': aDays[nDay].slice(0,3),
'%A': aDays[nDay],
'%b': aMonths[nMonth].slice(0,3),
'%B': aMonths[nMonth],
'%c': date.toUTCString(),
'%C': Math.floor(nYear/100),
'%d': zeroPad(nDate, 2),
'%e': nDate,
'%F': date.toISOString().slice(0,10),
'%G': getThursday().getFullYear(),
'%g': ('' + getThursday().getFullYear()).slice(2),
'%H': zeroPad(nHour, 2),
'%I': zeroPad((nHour+11)%12 + 1, 2),
'%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth>1 && isLeapYear()) ? 1 : 0), 3),
'%k': '' + nHour,
'%l': (nHour+11)%12 + 1,
'%m': zeroPad(nMonth + 1, 2),
'%M': zeroPad(date.getMinutes(), 2),
'%p': (nHour<12) ? 'AM' : 'PM',
'%P': (nHour<12) ? 'am' : 'pm',
'%s': Math.round(date.getTime()/1000),
'%S': zeroPad(date.getSeconds(), 2),
'%u': nDay || 7,
'%V': (function() {
var target = getThursday(),
n1stThu = target.valueOf();
target.setMonth(0, 1);
var nJan1 = target.getDay();
if (nJan1!==4) target.setMonth(0, 1 + ((4-nJan1)+7)%7);
return zeroPad(1 + Math.ceil((n1stThu-target)/604800000), 2);
})(),
'%w': '' + nDay,
'%x': date.toLocaleDateString(),
'%X': date.toLocaleTimeString(),
'%y': ('' + nYear).slice(2),
'%Y': nYear,
'%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
'%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
}[sMatch] || sMatch;
});
}
样品用法:
strftime('%F'); // Returns "2016-09-15"
strftime('%A, %B %e, %Y'); // Returns "Thursday, September 15, 2016"
// You can optionally pass it a Date object...
strftime('%x %X', new Date('1/1/2016')); // Returns "1/1/2016 12:00:00 AM"
最新代码可在此处获取:https://github.com/thdoan/strftime
就个人而言,因为我同时使用PHP和jQuery / javascript,我使用php.js中的日期函数http://phpjs.org/functions/date/
使用与我已经知道的相同格式字符串的库对我来说更容易,并且包含日期函数的所有格式字符串可能性的手册当然可以在php.net上在线
您只需使用首选方法在HTML中包含date.js文件,然后调用它:
var d1=new Date();
var datestring = date('Y-m-d', d1.valueOf()/1000);
如果需要,可以使用d1.getTime()而不是valueOf(),它们可以执行相同的操作。
除以1000的javascript时间戳是因为javascript时间戳以毫秒为单位,但PHP时间戳以秒为单位。
如果您已在项目中使用jQuery UI,则可以使用内置的datepicker方法格式化日期对象:
$.datepicker.formatDate('yy-mm-dd', new Date(2007, 1 - 1, 26));
但是,datepicker只格式化日期,不能格式化时间。
许多框架(您可能已经在使用)具有您可能不知道的日期格式。已经提到过jQueryUI,但是其他框架如Kendo UI (Globalization),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")
列出
Date()
对象支持的格式说明符的文档在哪里?
今天我偶然发现了这一点,并且很惊讶没有人花时间回答这个简单的问题。没错,有很多库可以帮助进行日期操作。有些人比其他人好。但这不是问题。
AFAIK,纯JavaScript不支持格式说明符,就像您表示要使用它们一样。但它确实支持格式化日期和/或时间的方法,例如.toLocaleDateString()
,.toLocaleTimeString()
和.toUTCString()
。
我经常使用的Date
对象参考是在w3schools.com website上(但a quick Google search会显示更多可能更符合您需求的对象)。
另请注意,“日期对象属性”部分提供了prototype
的链接,该部分说明了使用自定义方法扩展Date对象的一些方法。多年来,JavaScript社区中一直存在关于这是否是最佳实践的some debate,我并不是在鼓吹或反对它,只是指出它的存在。
对于固定格式,一个简单的功能可以完成工作。以下示例生成国际格式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开始,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的Stringifier。
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:Date的通用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);在最初提出这个问题时(2009年6月),标准是3(4被放弃),但是在2009年底之后不久发布了5个。这应该概述一个问题; javascript实现可能遵循什么标准,可能无法反映实际存在的内容,因为a)它是给定标准的实现,b)并非标准的所有实现都是清教徒,并且c)功能不是与a同步发布的新标准d)实施是一项持续不断的工作
从本质上讲,当处理javascript时,你正在处理一个实现的衍生物(特定于浏览器的javascript)(javascript本身)。例如,谷歌的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 ] ] ] ] ] )
这两个函数看起来都应该很熟悉,但这并不会立即回答您的问题以及量化为可接受的“日期格式”需要进一步解释。当你将一个字符串传递给新的Date()时,它将调用原型(请注意,我正在松散地使用单词prototype;版本可能是单个函数,或者它可能是单个函数中条件语句的一部分) new Date(value),其字符串作为“value”参数的参数。此函数将首先检查它是数字还是字符串。可以在此处找到此功能的文档:
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.3.2
由此,我们可以推断出为了获得新Date(值)允许的字符串格式,我们必须查看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中允许的格式代表了今天可用的所有格式,但我认为这是公平的假设他们确实遵循现代期望。
谷歌的V8,date.js,DateConstructor
https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#141
查看DateConstructor函数,我们可以推断出我们需要找到DateParse函数;但请注意,“年份”不是实际年份,而只是对“年”参数的引用。
谷歌的V8,date.js,DateParse
https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#270
这会调用%DateParseString,它实际上是C ++函数的运行时函数引用。它指的是以下代码:
谷歌的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在这里定义:
谷歌的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标准,如果它不符合标准,那么它将尝试基于旧格式构建日期。基于评论的几个关键点:
所以这应该足以让您基本了解将字符串传递给Date对象时会发生什么。您可以通过查看Mozilla在Mozilla开发者网络上指出的以下规范(符合IETF RFC 2822时间戳)来进一步扩展这一点:
Microsoft Developer Network还提到了Date对象的附加标准:ECMA-402,ECMAScript国际化API规范,它是对ECMAScript 5.1标准(以及未来标准)的补充。这可以在这里找到:
在任何情况下,这应该有助于突出显示没有普遍代表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/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
http://msdn.microsoft.com/en-us/library/ff743760(v=vs.94).aspx
确保在处理JavaScript中的日期时签出Datejs。在toString function的情况下,你可以看到它是非常令人印象深刻和有据可查的。
编辑:Tyler Forsythe指出,datejs已经过时了。我在我当前的项目中使用它并且没有任何问题,但是你应该意识到这一点并考虑替代方案。
您可以使用Date
指出的新format
方法扩展meizz对象,下面是作者给出的代码。这是一个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 spec保留了解析和输出格式功能,直到Javascript实现。 ECMAScript 5添加了ISO8601支持的子集。我相信你提到的toString()函数是一个浏览器的创新(Mozilla?)
有几个库提供了参数化的例程,其中一些具有广泛的本地化支持。您还可以查看dojo.date.locale中的方法。