重溫JavaScript中內置Date屬性

背景

在一個陰雨綿綿的早上,正在和基友們討論昨晚的多人運動應該團戰誰背鍋的問題。這時接到兩個需求:html

一、針對移動端寫一個顯示將來7天的日曆前端

二、當用戶查看一場會議時,根據用戶訪問的時間端不一樣,作出相應的指令。通俗點就是判斷時間差,當前訪問時間與會議開始時間之間的差。(以分鐘爲基礎單位)bash

兩個需求都有涉及到,對於時間Date的相關操做。函數

因此爲了晚上可以順利進行多人運動,所以我便開始了我時間管理求知之路。oop

Date實例

因此依照往常慣例,我打開求知路上的老朋友MDN。打算從新過一遍關於Date對象的相關文檔說明以後,再開始時間管理。ui

Date語法:spa

new Date();prototype

new Date(value);3d

new Date(dateString);code

new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);

哦豁,不查都忘記了,原來Date()構造函數有四種基本形式。

沒有參數

沒有參數,新建立的Date對象表示實例化時刻的日期和時間,第一種沒有參數的方法估計前端平常開發中頻率最高使用方法。

例如我對於Date()直接獲取當前日期顯示項目右上角或者左上角。再或者就是進一步經過getDay()獲取星期的阿拉伯數字,而後轉成中文日一二三四五六相關操做而已。 再稍微複雜一點的時間選擇需求,就是直接上一個第三方日曆組件了。

Unix時間戳:value

這裏的value填寫的一個Unix 時間戳,表示自1970年1月1日00:00:00 UTC(the Unix epoch)以來的毫秒數,忽略了閏秒。

例如我如今寫blog的時候是北京時間 2020-05-31 14:16:03

那麼與之對應的時間戳就是:159095764 (小貼士,這裏的value類型是整數字)

時間戳字符串: dateString

也就是符合即符合 IETF-compliant RFC 2822 timestampsversion of ISO8601 規則下的時間字符串。 例如說:

December 17, 1995 03:24:00

1995-12-17T03:24:00

這些字符串都是dateString, 固然有人可能說我不清楚是否我輸入了dateString是不是正確。這時能夠借用Date.parse()做爲基本的驗證。

Date.parse('2020-05-31T14:43:00')   //輸出:1590907380000
複製代碼

Date.parse() 方法解析一個表示某個日期的字符串,並返回從1970-1-1 00:00:00 UTC 到該日期對象(該日期對象的UTC時間)的毫秒數,若是該字符串沒法識別,或者一些狀況下,包含了不合法的日期數值(如:2015-02-31),則返回值爲NaN。

至關於咱們常見的new Date(dateString).getTime()

關於Date.parse()更多詳細的文檔說明,能夠移步到MDN - Date.parse()

填入時間日期的多個成員: year, monthIndex……

關於標題欄部分,爲何只填寫兩個詞語。由於year,monthIndex是必填項, 其他的day,hour等一些選項都是非選項。

new Date(2020,4)  // 輸出 Fri May 01 2020 00:00:00 GMT+0800 (中國標準時間) {}
複製代碼

當不填這些非選項時,會返回當月1號,00:00:00。(月份須要+1,這裏就不在敘說了,這個我相信你們都熟悉了。)

Date.prototype.setDate()

而後前面new Date(), 感受意猶未盡。總以爲只習得new Date()這一招感受不夠用,想着尋思有沒有相似直接給天數,而後可以自動算出後面的日期內置方法。

結果隨手一翻,還真找到一個setDate()有相似的做用。

語法:

dateObj.setDate(dayValue) setDate()

方法:根據本地時間來指定一個日期對象的天數。

其中參數的dayValue,一個整數,表示該月的第幾天。

let theDay = new Date(2020, 4, 30);   // Sat May 30 2020 00:00:00 GMT+0800 (中國標準時間) {}
  let setValue = theDay.setDate(20);   // 這裏直接返回new Date(2020, 4, 20).getTime()
  console.log(setValue === ( new Date(2020, 4, 20).getTime()));  // true
複製代碼

這裏有小夥伴可能就要問了,既然這個dayvalue是整數。那我這邊要是填寫 32 or -10, setDate()也可以正常解析嘛?

這也是setDate()好玩的地方,若是 dayValue 超出了月份的合理範圍,setDate 將會相應地更新 Date 對象。

例如:

dayValue 指定0,那麼日期就會被設置爲上個月的最後一天。

dayValue被設置爲負數,日期會設置爲上個月最後一天往前數這個負數絕對值天數後的日期。-1會設置爲上月最後一天的前一天.

dayValue設置超出該月份最大數值,則日期設置會下一個月開始依次計算。

let theDay = new Date(2020, 4, 30);   // Sat May 30 2020 00:00:00 GMT+0800 (中國標準時間) {}
let bigValue = theDay.setDate(32);   // theDay被設置成6月1號,
console.log(bigValue  === (new Date(2020, 5, 1).getTime()))   // 輸出:true
let smallValue = theDay.setDate(-1)  // 又被設置成 5月30日
console.log(smallValue === (new Date(2020, 4, 30).getTime()))  // 輸出:true
複製代碼

過了一遍文檔以後,那麼接下來就是摩拳擦掌整需求了。

7天日曆需求

需求一列日期,默認當天顯示在第一位。而後依次列出後面7天的日期和星期。

最上面一排星期卻是好算,獲取當天的星期,遞增循環+一個臨界值判斷就能刷刷的寫出來了。 有趣的是算日期,若是沒有細看前面的文檔,直接計算可能就須要判斷是不是閏年,屬於幾月會稍微有點麻煩。

可是咱們把前面文檔,那麼掌控這個日期時間就是手到勤來了。一個for循環,解決日期和星期。

const Calendar = []
const WeekStr = ['日','一', '二','三','四','五','六']
for(let i = 0; i< 8 ; i++) {
    Calendar[i] = {}
    let loopDate = new Date();
    let loopDay =  loopDate.getDate() + i;
    let loopValue = loopDate.setDate(loopDay)
    let newDate = new Date(loopValue)
    Calendar[i].day = newDate.getDate()
    Calendar[i].week = WeekStr[newDate.getDay()]
}
複製代碼

有趣,我都愛上我本身了。

時間差需求

關於時間差的需求。我一開始是沒有看文檔的。

腦中默認的想到就是獲取當前當前時刻的getTime(),而後會議開始時間的getTime()進行相減,而後再根據差值範圍進行條件判斷。

例如:

let start = new Date(2020,5,2,16, 30).getTime()
let now = new Date(2020, 5, 2, 15, 30).getTime()
console.log(start - now)   // 3600000, 換算就是60min
複製代碼

後面翻閱了文檔發現,還有Date.now()屬性和getTime()也有殊途同歸之效

let start = new Date(2020,5,2,16, 30).now()
let now = new Date(2020, 5, 2, 15, 30).now()
console.log(start - now) // 3600000, 換算就是60min
複製代碼

最後應用到項目上時,我使用成熟的解決方案dayjs, 固然與之相似的還有monent.js

小結

簡單的兩個需求讓我從新回顧了Date(), 瞭解new Date()更多的用法,以及setDate()組合出神奇化學反應。

至於時間差需求,明明能夠直接算出來的方法。卻還須要引用第三方庫day.js一類呢?

由於因爲不一樣日期、月份、年份長度的不一樣(日期長度不一樣來自夏令時的切換),使用大於秒、分鐘、小時的單位表示通過的時間會遇到不少問題,在使用前須要通過詳盡的調研。

研究琢磨一番卻是能夠,可是立刻拿到項目中,這種成熟穩定第三方庫難道不香嘛? 我可不是爲了偷懶要去多人運動

最後帶我王者嘛! 墨三炮賊溜。

相關文章
相關標籤/搜索