new Date(Date.parse("Jul 8, 2005"));
2005年7月8日星期五00:00:00 GMT-0700(PST) javascript
new Date(Date.parse("2005-07-08"));
Thu Jul 07 2005 17:00:00 GMT-0700(PST) html
爲何第二次解析不正確? java
根據http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html的格式,「 yyyy / mm / dd」解決了常見問題。 他說:「請儘量將日期字符串粘貼到「 YYYY / MM / DD」。它被廣泛支持且明確。使用這種格式,全部時間都在本地。 我已經設置了測試: http : //jsfiddle.net/jlanus/ND2Qg/432/此格式:+經過使用ymd排序和4位數字的年份避免了日和月順序的歧義+避免了UTC與本地問題的衝突dygraphs的傢伙經過使用斜槓+ danvk來符合ISO格式,他說這種格式在全部瀏覽器中都很好。 mysql
另外一種解決方案是用日期格式構建一個關聯數組,而後從新格式化數據。 c++
此方法對於以異常方式格式化日期頗有用。 sql
一個例子: 數組
mydate='01.02.12 10:20:43': myformat='dd/mm/yy HH:MM:ss'; dtsplit=mydate.split(/[\/ .:]/); dfsplit=myformat.split(/[\/ .:]/); // creates assoc array for date df = new Array(); for(dc=0;dc<6;dc++) { df[dfsplit[dc]]=dtsplit[dc]; } // uses assc array for standard mysql format dstring[r] = '20'+df['yy']+'-'+df['mm']+'-'+df['dd']; dstring[r] += ' '+df['HH']+':'+df['MM']+':'+df['ss'];
這個輕量級的日期解析庫應該解決全部相似的問題。 我喜歡該庫,由於它很容易擴展。 也有可能(不是很簡單,可是就不那麼難了)。 瀏覽器
解析示例: 安全
var caseOne = Date.parseDate("Jul 8, 2005", "M d, Y"); var caseTwo = Date.parseDate("2005-07-08", "Y-m-d");
而後格式化回字符串(您會注意到兩種狀況給出的結果徹底相同): 函數
console.log( caseOne.dateFormat("M d, Y") ); console.log( caseTwo.dateFormat("M d, Y") ); console.log( caseOne.dateFormat("Y-m-d") ); console.log( caseTwo.dateFormat("Y-m-d") );
在最近寫JS解釋器的經驗中,我爲ECMA / JS日期的內部工做付出了不少努力。 所以,我認爲我將在這裏投入2美分。 但願共享這些內容能夠幫助其餘人解決有關瀏覽器在處理日期方面的差別的任何問題。
全部實如今內部將其日期值存儲爲64位數字,這些數字表示自1970年1月1日UTC以來的毫秒數(GMT與UTC是同一件事)。 1/1/1970 00:00:00
以後的日期爲正數,而以前的日期爲負數。
所以,如下代碼在全部瀏覽器上都產生徹底相同的結果。
Date.parse('1/1/1970');
在個人時區(EST),結果是1800萬,由於這是5個小時內的毫秒數(在夏令時中只有4個小時)。 在不一樣的時區,該值將有所不一樣。 全部主要的瀏覽器都以相同的方式進行操做。
這是擦。 儘管主要瀏覽器會將輸入字符串格式解析爲日期存在一些差別,但就時區和夏令時而言,它們基本上將它們解釋爲相同的形式。 支持的一種是ISO 8601格式。 這是ECMA-262 v.5規範中概述的惟一格式。 對於全部其餘字符串格式,解釋取決於實現。 具備諷刺意味的是,這是瀏覽器能夠不一樣的格式。 這是個人計算機上使用ISO 8601字符串格式的1970年1月1日Chrome和Firefox的比較輸出。
Date.parse('1970-01-01T00:00:00Z'); // Chrome: 0 FF: 0 Date.parse('1970-01-01T00:00:00-0500'); // Chrome: 18000000 FF: 18000000 Date.parse('1970-01-01T00:00:00'); // Chrome: 0 FF: 18000000
toString
的輸出以匹配個人輸入值,除非我指定了備用時區,不然我永遠不會這樣作。 沒有指定符應假定本地時間輸入。 可是,狀況變得更糟的是,FF處理ISO 8601格式的短格式(「 YYYY-MM-DD」)與處理長格式(「 YYYY-MM-DDTHH:mm:ss:sssZ」)的方式有所不一樣沒有任何邏輯上的緣由。 這是FF的輸出,帶有長和短ISO日期格式,沒有時區說明符。
Date.parse('1970-01-01T00:00:00'); // 18000000 Date.parse('1970-01-01'); // 0
所以,要直接回答原始提問者的問題, "YYYY-MM-DD"
是ISO 8601格式"YYYY-MM-DDTHH:mm:ss:sssZ"
。 所以,它被解釋爲UTC時間,而另外一個被解釋爲本地時間。 這就是爲何,
console.log(new Date(Date.parse("Jul 8, 2005")).toString()); console.log(new Date(Date.parse("2005-07-08")).toString());
console.log(new Date(Date.parse("Jul 8, 2005")).toString()); console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());
底線是用於解析日期字符串的。 長格式是您能夠在瀏覽器中安全解析的惟一ISO 8601字符串。 而且,始終使用「 Z」說明符。 若是這樣作,則能夠安全地在本地時間和UTC時間之間來回切換。
console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());
幸運的是,大多數當前的瀏覽器的確能平等對待其餘輸入格式,包括最經常使用的「 1/1/1970」和「 1/1/1970 00:00:00 AM」格式。 如下全部格式(以及其餘格式)在全部瀏覽器中均視爲本地時間輸入,並在存儲前轉換爲UTC。 所以,使它們跨瀏覽器兼容。 在我所在時區的全部瀏覽器中,此代碼的輸出都是相同的。
console.log(Date.parse("1/1/1970")); console.log(Date.parse("1/1/1970 12:00:00 AM")); console.log(Date.parse("Thu Jan 01 1970")); console.log(Date.parse("Thu Jan 01 1970 00:00:00")); console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));
在輸出端,全部瀏覽器都以相同的方式轉換時區,可是它們對字符串格式的處理方式不一樣。 這是toString
函數及其輸出。 請注意,個人機器上凌晨5:00輸出的toUTCString
和toISOString
函數。
在打印以前從UTC轉換爲本地時間
- toString - toDateString - toTimeString - toLocaleString - toLocaleDateString - toLocaleTimeString
直接打印存儲的UTC時間
- toUTCString - toISOString
In Chrome
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time) toDateString Thu Jan 01 1970 toTimeString 00:00:00 GMT-05:00 (Eastern Standard Time) toLocaleString 1/1/1970 12:00:00 AM toLocaleDateString 1/1/1970 toLocaleTimeString 00:00:00 AM toUTCString Thu, 01 Jan 1970 05:00:00 GMT toISOString 1970-01-01T05:00:00.000Z
In Firefox
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time) toDateString Thu Jan 01 1970 toTimeString 00:00:00 GMT-0500 (Eastern Standard Time) toLocaleString Thursday, January 01, 1970 12:00:00 AM toLocaleDateString Thursday, January 01, 1970 toLocaleTimeString 12:00:00 AM toUTCString Thu, 01 Jan 1970 05:00:00 GMT toISOString 1970-01-01T05:00:00.000Z
我一般不使用ISO格式輸入字符串。 只有當日期須要按字符串排序時,使用這種格式對我有用的惟一時間。 ISO格式能夠按原樣排序,而其餘格式則不能。 若是必須具備跨瀏覽器的兼容性,請指定時區或使用兼容的字符串格式。
代碼new Date('12/4/2013').toString()
通過如下內部僞轉換:
"12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"
我但願這個答案會有所幫助。
在第5版規範發佈以前, Date.parse
方法徹底依賴於實現 ( new Date(string)
等效於Date.parse(string)
但後者返回一個數字而不是Date
)。 在第5版規範中,添加了該要求以支持簡化的(而且略有錯誤) ISO-8601 (另請參見JavaScript中有效的日期時間字符串是什麼? )。 可是除此以外,除了必須接受任何Date#toString輸出(不說那是什麼)以外, 沒有要求Date.parse
/ new Date(string)
應該接受什麼。
從ECMAScript 2017(版本8)開始,要求實現解析Date#toString和Date#toUTCString的輸出 ,但未指定這些字符串的格式。
從ECMAScript 2019(版本9)開始, Date#toString和Date#toUTCString的格式分別指定爲:
提供了另外2種格式, Date.parse應該在新的實現中可靠地對其進行解析(請注意,該支持並非廣泛存在的,而且不兼容的實現將在一段時間內繼續使用)。
我建議手動解析日期字符串,並將Date構造函數與年,月和日參數一塊兒使用,以免產生歧義:
// parse a date in yyyy-mm-dd format function parseDate(input) { var parts = input.split('-'); // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]]) return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based }