dayjs 源碼解析(一)(api)

前言

做爲一個程序員,閱讀別人優秀代碼是提高本身技術能力的一個很好的方法。下面,我將本身閱讀 dayjs(v1.6.10)的源碼的過程記錄下來。javascript

閱讀庫的代碼,首先先要知道這個庫的做用

dayjs 是一個輕量的 JavaScript 時間日期處理庫,其用法(api)和 Moment.js 徹底同樣。java

特色

  • 和 Moment.js 相同的 api 和用法
  • 不可變數據(Immutable)
  • 支持鏈式操做(Chainable)
  • l18n國際化
  • 僅 2kb 大小
  • 全瀏覽器兼容

由於其 api 和 Moment.js 徹底相同,因此你能夠將以前使用 Moment.js 的項目無痛的遷移使用 dayjs。git

API 介紹(v1.6.10)

首先,閱讀 dayjs 的源碼,咱們應該從 dayjs 的 api 入手。程序員

官方 api 文檔(中文) 官方 api 文檔(英文)github

Day.js 沒有修改原生的 Date.prototype,而是在 Date 對象基礎上包裝了一層,叫作 Dayjs 對象。Dayjs 對象是不可變的,即全部改變 Dayjs 的操做都會返回一個新的實例。json

其中,api 分爲 6 類:segmentfault

  • 解析api

    • 構造 dayjs(existing?:string | number | Date | Dayjs):構造一個 Dayjs 實例對象
    • 克隆 .clone() | dayjs(original: Dayjs):在已有 Dayjs 實例對象的基礎上克隆返回一個新的 Dayjs 實例對象
    • 驗證 .isValid():驗證該 Dayjs 實例對象是否有效
  • 獲取和設置數組

    • 年 .year()
    • 月 .month()
    • 日 .date()
    • 星期幾 .day()
    • 時 .hour()
    • 分 .minute()
    • 秒 .second()
    • 毫秒 .millisecond()
    • 設置 .set(unit: string, value: number)
  • 操做瀏覽器

    • 添加 .add(value: number, unit: string)
    • 減小 .subtract(value: number, unit: string)
    • 開始的時間 .startOf(unit: string)
    • 結束的時間 .endOf(unit: string)
  • 展現

    • 格式化 .format(stringWithTokens: string)
    • 差異 .diff(compared: Dayjs, unit: string (default: 'milliseconds'), float?: boolean)
    • Unix 時間戳(毫秒) .valueOf()
    • Unix 時間戳(秒) .unix()
    • 某月的天數 .daysInMonth()
    • 轉換爲 JavaScript Date 對象 .toDate
    • 轉換爲數組 .toArray()
    • 轉換爲 JSON .toJSON()
    • 轉換爲 ISO 8601 標準格式的字符串 .toISOString()
    • 轉換爲對象 .toObject()
    • 轉換爲字符串 .toString()
  • 查詢

    • 是否在以前 .isBefore(compared: Dayjs)
    • 是否相同 .isSame(compared: Dayjs)
    • 是否在以後 .isAfter(compared: Dayjs)
    • 是不是 Dayjs 實例對象 isDayjs()
  • 插件

    • 相對時間
    • 是不是閏年

API 詳解(v1.6.10)

解析

構造器 dayjs(existing?: string | number | Date | Dayjs)

1.當沒有參數時,會返回一個新的 Dayjs 實例對象,且爲當前日期和時間

dayjs()

2.當參數爲 ISO 8601 標準的字符串時

dayjs('2018-07-01T12:00:00.000Z')

3.當參數爲 unix 時間戳時

dayjs(1318781876406);

4.當參數爲一個原生的 JavaScript Date 對象時

dayjs(new Date(2018, 7, 1));

dayjs() 構造函數會返回一個 Dayjs 實例對象

克隆 .clone() | dayjs(original: Dayjs)

會克隆返回一個新的 Dayjs 對象,有兩種方法

// 1.使用 .clone() 方法
dayjs().clone()

// 2.使用 dayjs 構造函數,且傳入的參數爲被克隆的 Dayjs 實例對象
dayjs(dayjs('2018-7-1'))

驗證 .isValid()

返回一個布爾值,表示該 Dayjs 實例對象是否有效

dayjs().isValid()

獲取和設置

獲取(年,月,日,星期幾,時,分,秒,毫秒)

// 年
dayjs().year()

// 月 
dayjs().month()

// 日
dayjs().date()

// 星期幾
dayjs().day()

// 時
dayjs().hour()

// 分
dayjs().minute()

// 秒
dayjs().second()

// 毫秒
dayjs().millisecond()

上面返回的值與用原生 Date.prototype 對象下的方法獲取 「年月日...」 的值是同樣的,其實在源碼中,就是使用的 Date 的原生方法獲取的 「年月日...」

設置 .set(unit: string, value: number)

返回一個新的日期時間被改變的 Dayjs 實例對象

dayjs().set('date', 1) // 設置 「日」 爲 1 日
dayjs().set('month', 3) // 設置 「月」 爲 4 月
dayjs().set('second', 30) // 設置 「秒」 爲 30 秒

操做

Dayjs 實例對象可使用不少方法操做

dayjs('2018-7-1')
  .add(1, 'day')
  .substract(1, 'year').toString()
// 在 2018-7-1 基礎上添加 1 天,而後減小 1 年,最後轉換爲字符串

添加 .add(value: number, unit: string)

dayjs().add(7. 'day')

減小 .subtract(value: number, unit: string)

dayjs().subtract(7. 'year')

開始的時間

返回克隆的以傳入的單位開始時間的 Dayjs 實例對象

dayjs().startOf('week') // 本週開始的時間

結束的時間

返回克隆的以傳入的單位結束時間的 Dayjs 實例對象

dayjs().endOf('month') // 本月的結束時間

展現

格式化 .format(stringWidthTokens: string)

返回一個按照你規定好的格式化後的字符串

dayjs().format(); // current date in ISO6801, without fraction seconds e.g. '2020-04-02T08:02:17-05:00'

dayjs('2019-01-25').format('{YYYY} MM-DDTHH:mm:ssZ[Z]'); // '{2019} 01-25T00:00:00-02:00Z'

dayjs('2019-01-25').format('DD/MM/YYYY'); // '25/01/2019'

可用的格式

差異 .diff(compared: Dayjs, unit: string (default: 'milliseconds'), float?: boolean)

返回兩個 Dayjs 實例對象的時間差

const date1 = dayjs('2019-01-25');
const date2 = dayjs('2018-06-05');
date1.diff(date2); // 20214000000
date1.diff(date2, 'months'); // 7
date1.diff(date2, 'months', true); // 7.645161290322581
date1.diff(date2, 'days'); // 233

unix 時間戳(毫秒) .valueOf()

dayjs('2019-01-25').valueOf(); // 1548381600000

unix 時間戳(秒) .unix()

dayjs('2019-01-25').unix(); // 1548381600

某月的天數 .daysInMonth()

dayjs('2018-7-1').daysInMonth() // 31

轉換爲(原生 Date 對象 | 數組 | json | ISO 8601 字符串 | 對象 | 字符串)

// 1.轉換爲 原生 Date 對象
dayjs('2019-01-25').toDate() 

// 2.轉換爲 數組
dayjs('2019-01-25').toArray() // [ 2019, 0, 25, 0, 0, 0, 0 ]

// 3.轉換爲 json
dayjs('2019-01-25').toJSON() // '2019-01-25T02:00:00.000Z'

// 4.轉換爲 ISO 8601 字符串
dayjs('2019-01-25').toISOString() // '2019-01-25T02:00:00.000Z'

// 5.轉換爲 ISO 8601 字符串
dayjs('2019-01-25').toObject()
/* { years: 2019,
     months: 0,
     date: 25,
     hours: 0,
     minutes: 0,
     seconds: 0,
     milliseconds: 0 } */
     
// 6.轉換爲 字符串
dayjs('2019-01-25').toString() // 'Fri, 25 Jan 2019 02:00:00 GMT'

查詢

是否在以前 .isBefore(compared: Dayjs)

dayjs().isBefore(dayjs()); // false

是否相同

dayjs().isSame(dayjs()); // true

是否在以後

dayjs().isAfter(dayjs()); // false

是不是 Dayjs 實例對象

dayjs.isDayjs(dayjs()); // true
dayjs.isDayjs(new Date()); // false

是不是閏年(在 1.7.0 版本被棄用,請使用 IsLeapYear plugin 插件替代)

dayjs('2000-01-01').isLeapYear(); // true

插件

相對時間

使用 .from .to .fromNow .toNow 方法來得到相對時間

是不是閏年

使用 .from .to .fromNow .toNow 方法來得到相對時間

下一篇,dayjs 源碼解析(二)(目錄結構)

相關文章
相關標籤/搜索