JavaScript 的 Date 最詳細解讀
基礎的 Date()
就不說了~ : )
如何獲得某個月的天數?
不知道大家遇到過這個問題嗎?我想如果你們寫過日期元件一定有這個問題,我當時的解決方案是這樣的:
以下的三個方法,month 引數我都根據 JS 本身對於 Date 的月份定義,採用0為1月
最老實的辦法
const EVERY_MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; function getDays(year, month) { if (month === 1 && isLeap(year)) return 29; return EVERY_MONTH_DAYS[month]; }
手動做了每個月天數的對映,如果是2月份並閏年,那天數+1
隨便安利一個自己寫的 osx 上的日曆外掛 https://github.com/lishengzxc/ng2-calendar
那沒有更好的方法呢?手動 map 和閏年判斷的邏輯沒有就好了。
稍微 diao 一點的辦法
function getDays(year, month) { if (month === 1) return new Date(year, month, 29).getMonth() === 1 ? 29 : 28; return new Date(year, month, 31).getMonth() === month ? 31 : 30; }
我們發現,new Date()
的第三個引數是可以大於我們所知的每個月的最後一天的的,比如:
new Date(2016, 0, 200) //Mon Jul 18 2016 00:00:00 GMT+0800 (CST)
這樣,我們就利用這個 JS 的特性,用29和31這兩個關鍵點,去判斷除了那個月的最後一天+1還是那個月嗎?(其實28和30是關鍵點)。
再稍微 diao 一點的方法
function getDays(year, month) { return new Date(year, month + 1, 0).getDate(); }
new Date()
的第三個引數傳小於1的值會怎麼樣了,比如傳0,我們就獲得了上個月的最後一天,當然傳負數也沒問題:
new Date(2016, 0, -200) //Sun Jun 14 2015 00:00:00 GMT+0800 (CST)
Date.prototype.各種String
具體的文件解釋懶得再複製一下給大家看,參考連結:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
這裡主要和大家普及以下知識:
GMT(格林尼治平時)
格林尼治平時(又稱格林尼治平均時間或格林尼治標準時間,舊譯格林威治標準時間;英語:Greenwich Mean Time,GMT)是指位於英國倫敦郊區的皇家格林尼治天文臺的標準時間,因為本初子午線被定義在通過那裡的經線。
自1924年2月5日開始,格林尼治天文臺每隔一小時會向全世界發放調時資訊。
理論上來說,格林尼治標準時間的正午是指當太陽橫穿格林尼治子午線時(也就是在格林尼治上空最高點時)的時間。由於地球在它的橢圓軌道里的運動速度不均勻,這個時刻可能與實際的太陽時有誤差,最大誤差達16分鐘。
由於地球每天的自轉是有些不規則的,而且正在緩慢減速,因此格林尼治時間已經不再被作為標準時間使用。現在的標準時間,是由原子鐘報時的協調世界時(UTC)。
所以我們也從 MDN 上的文件看到對於toGMTString()
的解釋是:
Returns a string representing the Date based on the GMT (UT) time zone. Use toUTCString() instead.
UTC(世界標準時間)
協調世界時,又稱世界標準時間或世界協調時間,簡稱UTC(從英文「Coordinated Universal Time」/法文「Temps Universel Cordonné」而來),是最主要的世界時間標準,其以原子時秒長為基礎,在時刻上儘量接近於格林尼治平時
CST(北京時間)
北京時間,China Standard Time,中國標準時間。在時區劃分上,屬東八區,比協調世界時早8小時,記為UTC+8。
不過這個CST這個縮寫比較糾結的是它可以同時代表四個不同的時間:
- Central Standard Time (USA) UT-6:00
- Central Standard Time (Australia) UT+9:30
- China Standard Time UT+8:00
- Cuba Standard Time UT-4:00
總結就是,前後端去傳時間的時候,儘量都用 UTC 時間。
ISO 日期和時間的表示方法
if ( !Date.prototype.toISOString ) { ( function() { function pad(number) { if ( number < 10 ) { return '0' + number; } return number; } Date.prototype.toISOString = function() { return this.getUTCFullYear() + '-' + pad( this.getUTCMonth() + 1 ) + '-' + pad( this.getUTCDate() ) + 'T' + pad( this.getUTCHours() ) + ':' + pad( this.getUTCMinutes() ) + ':' + pad( this.getUTCSeconds() ) + '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + 'Z'; }; }() ); }
通過 Polyfill 我們就能知道 ISO 是怎麼表示時間的,最主要的特徵是最後一位是“Z”,然後表示的總是 UTC 時間。
額外的補充
.valueOf() 和 .getTime()
.valueOf()
的功能和.getTime()
一樣。
該方法通常在 JavaScript 內部被呼叫,而不是在程式碼中顯式呼叫。什麼意思?沒有 valueOf
,那麼Date
的例項是不能進行運算的。
var obj = Object.create(null); obj + 1; // Uncaught TypeError: Cannot convert object to primitive value(…)
.toJSON
直接看這個 API 的名字的時候,我以為會返回一個 JSON 格式的字串,但其實是這麼一個東西
new Date().toJSON() // "2016-05-05T06:03:28.130Z"
其實是這麼回事
JSON.stringify(new Date()) // ""2016-05-05T06:06:02.615Z""
那結果能夠被 parse 嗎?
JSON.parse(JSON.stringify(new Date())) // "2016-05-05T06:19:24.766Z" JSON.parse('"' + new Date().toJSON() + '"') // "2016-05-05T06:19:24.766Z"
但是結果只是字串而已。需要再講這個字串交給 new Date()
才行。
.toLocaleFormat()
不屬於任何標準。在JavaScript 1.6中被實現。似乎也只有 Firefox 自持這個 API,其實正確姿勢是用.toLocaleDateString()
.toLocale各種String()
.toLcale各種String(locales [, options]])
媽的這個 API 有點煩,看 MDN 的文件你就知道。這個 API 是用來本地化時間的。
這裡稍微說下我對這些引數的理解:
locales
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); // formats below assume the local time zone of the locale; // America/Los_Angeles for the US // US English uses month-day-year order alert(date.toLocaleString("en-US")); // → "12/19/2012, 7:00:00 PM" // British English uses day-month-year order alert(date.toLocaleString("en-GB")); // → "20/12/2012 03:00:00" // Korean uses year-month-day order alert(date.toLocaleString("ko-KR")); // → "2012. 12. 20. 오후 12:00:00" // Arabic in most Arabic speaking countries uses real Arabic digits alert(date.toLocaleString("ar-EG")); // → "٢٠/١٢/٢٠١٢ ٥:٠٠:٠٠ ص" // for Japanese, applications may want to use the Japanese calendar, // where 2012 was the year 24 of the Heisei era alert(date.toLocaleString("ja-JP-u-ca-japanese")); // → "24/12/20 12:00:00" // when requesting a language that may not be supported, such as // Balinese, include a fallback language, in this case Indonesian alert(date.toLocaleString(["ban", "id"])); // → "20/12/2012 11.00.00"
以locales
所指的地區的時區和語言輸出。
options
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString
localeMatcher
選擇本地匹配的什麼演算法,似乎沒什麼大用timeZone
再設定下 UTC 時區hour12
是否12小時制formatMatcher
各日期時間單元的格式化weekday
Possible values are"narrow", "short", "long"
.era
Possible values are"narrow", "short", "long"
.year
Possible values are"numeric", "2-digit"
.month
Possible values are"numeric", "2-digit", "narrow", "short", "long"
.day
Possible values are"numeric", "2-digit"
.hour
Possible values are"numeric", "2-digit"
.minute
Possible values are"numeric", "2-digit"
.second
Possible values are"numeric", "2-digit"
.timeZoneName
Possible values are"short", "long"
.
栗子:
var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0)); date.toLocaleString("en-US", {hour12: false}); // "12/19/2012, 19:00:00" var options = {timeZoneName:'long',weekday: "long", year: "2-digit", month: "narrow", day: "numeric"}; date.toLocaleString("en-US", options); // "Thursday, D 20, 12, China Standard Time"
插一個JavaScript 顯示 Y-m-d H:i:s 的日期時間格式
老實的方法
let date = new Date(); let result = [ [ date.getFullYear(), date.getMonth() + 1, date.getDate() ].join('-'), [ date.getHours(), date.getMinutes(), date.getSeconds() ].join(':') ].join(' ').replace(/\b\d\b/g, '0$&');
diao 一點的方法
var date = new Date(); var result = date.toLocaleString('zh-CN', { hour12: false }) .replace(/\//g, '-').replace(/\b\d\b/g, '0$&');
一些有用的時間庫
相關文章
- 史上最詳細ConvLstm的pytorch程式碼解讀分析PyTorch
- 史上最為詳細的javascript繼承JavaScript繼承
- SqueezeNet詳細解讀
- njs最詳細的入門手冊:Nginx JavaScript EngineJSNginxJavaScript
- 全網最詳細解讀《GIN-HOW POWERFUL ARE GRAPH NEURAL NETWORKS》!!!
- 可能是最詳細的字元編碼詳解字元
- vue的事件冒泡 最詳細解釋版本Vue事件
- mysql 5.7配置項最詳細的解釋MySql
- Kafka原始碼篇 --- 可能是你看過最詳細的RecordAccumulator解讀Kafka原始碼
- 詳細解讀go語言中的chnanelGoNaN
- 手寫 Promise 詳細解讀Promise
- 這應該是全網最詳細的Vue3.5版本解讀Vue
- 詳細解讀微服務的兩種模式微服務模式
- JavaScript Date()JavaScript
- Oracle SCN機制詳細解讀Oracle
- 矩陣分解--超詳細解讀矩陣
- Android BLE藍芽詳細解讀Android藍芽
- iozone磁碟讀寫測試工具的使用以及命令詳解、下載(網站最詳細講解步驟)網站
- 詳細資訊用於javascript中的承諾使用詳解JavaScript
- Element-ui(更新中表單最詳細的解釋)UI
- 全網最詳細的負載均衡原理圖解負載圖解
- openstack完整的部署(最詳細)
- 史上最詳細的一線大廠Mysql面試題詳解MySql面試題
- Java面試-List中的sort詳細解讀Java面試
- C++指標的概念解讀 超詳細C++指標
- 詳細解讀Service Mesh的資料面Envoy
- EventBus 3.0+ 原始碼詳解(史上最詳細圖文講解)原始碼
- Semaphore最詳細解析
- Redis 主從複製詳細解讀Redis
- 手寫 call apply bind 詳細解讀APP
- A*尋路演算法詳細解讀演算法
- 詳細解讀阿里手冊之MySQL阿里MySql
- JavaScript Date() 方法JavaScript
- JavaScript Date valueOf()JavaScript
- JavaScript Date 物件JavaScript物件
- 教科書級講解,秒懂最詳細Java的註解Java
- 最詳細的測試用例設計方法講解
- 最全面最詳細的字符集講解來了!
- javascript this詳細介紹JavaScript