美文网首页
DayJs源码(四)Dayjs类中API

DayJs源码(四)Dayjs类中API

作者: 小q | 来源:发表于2021-05-06 23:18 被阅读0次

    Dayjs中的API被定义在Dayjs类中,因为有很多,所以这里将挑选部分来记录。

    • isValid() 验证Day.js对象是否包含有效日期。

    isValid() {
        return !(this.$d.toString() === C.INVALID_DATE_STRING) // Invalid Date
     }
    

    • startOf()方法 定义开始时间

      startOf(units, startOf) { // startOf -> endOf
        const isStartOf = !Utils.u(startOf) ? startOf : true // startof调用时不传,endof调用时传false
        const unit = Utils.p(units) // 解析以什么单位开始
        const instanceFactory = (d, m) => {
          const ins = Utils.w(this.$u ?
            Date.UTC(this.$y, m, d) : new Date(this.$y, m, d), this)
          return isStartOf ? ins : ins.endOf(C.D)
        }
        const instanceFactorySet = (method, slice) => {
          const argumentStart = [0, 0, 0, 0]
          const argumentEnd = [23, 59, 59, 999] 
          return Utils.w(this.toDate()[method].apply( // eslint-disable-line prefer-spread // Utils.w 就是wrapper方法
            this.toDate('s'),
            (isStartOf ? argumentStart : argumentEnd).slice(slice)
          ), this)
        }
        const { $W, $M, $D } = this
        const utcPad = `set${this.$u ? 'UTC' : ''}` // UTC() 方法可根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数
        switch (unit) {
          case C.Y: // 选择年
            return isStartOf ? instanceFactory(1, 0) :
              instanceFactory(31, 11)
          case C.M: // 选择分钟
            return isStartOf ? instanceFactory(1, $M) :
              instanceFactory(0, $M + 1)
          case C.W: { // 选择星期
            const weekStart = this.$locale().weekStart || 0
            const gap = ($W < weekStart ? $W + 7 : $W) - weekStart
            return instanceFactory(isStartOf ? $D - gap : $D + (6 - gap), $M)
          }
          case C.D: // 选择天
          case C.DATE:
            return instanceFactorySet(`${utcPad}Hours`, 0)
          case C.H: // 选择时
            return instanceFactorySet(`${utcPad}Minutes`, 1)
          case C.MIN: // 选择分
            return instanceFactorySet(`${utcPad}Seconds`, 2)
          case C.S: // 选择秒
            return instanceFactorySet(`${utcPad}Milliseconds`, 3)
          default:
            return this.clone()
        }
      }
    
      endOf(arg) {
        return this.startOf(arg, false)
      }
    
    • format方法
      format(formatStr) {
        if (!this.isValid()) return C.INVALID_DATE_STRING // return Invalid Date
    
        const str = formatStr || C.FORMAT_DEFAULT // 不传的话按YYYY-MM-DDTHH:mm:ssZ格式
        const zoneStr = Utils.z(this) // Utils.z 为 padZoneStr方法 ,具体如下Utils中代码
        const locale = this.$locale()
        const { $H, $m, $M } = this
        const {
          weekdays, months, meridiem
        } = locale
        const getShort = (arr, index, full, length) => ( // 返回月份,如Aug || August
          (arr && (arr[index] || arr(this, str))) || full[index].substr(0, length)
        )
        const get$H = num => (
          Utils.s($H % 12 || 12, num, '0')
        )
    
        const meridiemFunc = meridiem || ((hour, minute, isLowercase) => { // 返回 大小写的上/下午
          const m = (hour < 12 ? 'AM' : 'PM')
          return isLowercase ? m.toLowerCase() : m
        })
    
        const matches = {
          YY: String(this.$y).slice(-2), // 如2021,截取21
          YYYY: this.$y, // 2021
          M: $M + 1, // 1
          MM: Utils.s($M + 1, 2, '0'), // 01
          MMM: getShort(locale.monthsShort, $M, months, 3), // Aug
          MMMM: getShort(months, $M), // August
          D: this.$D, // 1
          DD: Utils.s(this.$D, 2, '0'), // 01
          d: String(this.$W),
          dd: getShort(locale.weekdaysMin, this.$W, weekdays, 2),
          ddd: getShort(locale.weekdaysShort, this.$W, weekdays, 3),
          dddd: weekdays[this.$W],
          H: String($H),
          HH: Utils.s($H, 2, '0'),
          h: get$H(1),
          hh: get$H(2),
          a: meridiemFunc($H, $m, true), // am || pm
          A: meridiemFunc($H, $m, false), // AM || PM
          m: String($m),
          mm: Utils.s($m, 2, '0'), // Utils.s 为padStart方法
          s: String(this.$s),
          ss: Utils.s(this.$s, 2, '0'),
          SSS: Utils.s(this.$ms, 3, '0'),
          Z: zoneStr // 'ZZ' logic below
        }
    
        return str.replace(C.REGEX_FORMAT, (match, $1) => $1 || matches[match] || zoneStr.replace(':', '')) // 'ZZ'
      }
    
    // utils.js
    const padStart = (string, length, pad) => {
      const s = String(string)
      if (!s || s.length >= length) return string
      return `${Array((length + 1) - s.length).join(pad)}${string}` // 在前面拼接“0”如padStart(3,2,'0'),返回“03”
    }
    
    const padZoneStr = (instance) => {
      const negMinutes = -instance.utcOffset() // 返回格林威治时间和本地时间之间的时差
      const minutes = Math.abs(negMinutes)
      const hourOffset = Math.floor(minutes / 60)
      const minuteOffset = minutes % 60 
      return `${negMinutes <= 0 ? '+' : '-'}${padStart(hourOffset, 2, '0')}:${padStart(minuteOffset, 2, '0')}` // 返回如 +03:30
    }
    
    // index.js
      utcOffset() {
        // Because a bug at FF24, we're rounding the timezone offset around 15 minutes
        //因为FF24有一个bug,我们将时区偏移取整为15分钟
        // https://github.com/moment/moment/pull/1871
        return -Math.round(this.$d.getTimezoneOffset() / 15) * 15 // 返回格林威治时间和本地时间之间的时差,以分钟为单位
      }
    
    • diff方法
      diff(input, units, float) {
        const unit = Utils.p(units) // Utils中 prettyUnit 方法
        const that = dayjs(input)
        const zoneDelta = (that.utcOffset() - this.utcOffset()) * C.MILLISECONDS_A_MINUTE // 60 * 1e3
        const diff = this - that
        let result = Utils.m(this, that)
    
        result = {
          [C.Y]: result / 12,
          [C.M]: result,
          [C.Q]: result / 3,
          [C.W]: (diff - zoneDelta) / C.MILLISECONDS_A_WEEK,
          [C.D]: (diff - zoneDelta) / C.MILLISECONDS_A_DAY,
          [C.H]: diff / C.MILLISECONDS_A_HOUR,
          [C.MIN]: diff / C.MILLISECONDS_A_MINUTE,
          [C.S]: diff / C.MILLISECONDS_A_SECOND
        }[unit] || diff // milliseconds
    
        return float ? result : Utils.a(result)
      }
    

    以上是Dayjs类中部分API,接下来会总结DayJs插件

    相关文章

      网友评论

          本文标题:DayJs源码(四)Dayjs类中API

          本文链接:https://www.haomeiwen.com/subject/zmmjdltx.html