docs: function toDateString (date, format, options) {
    if (date) {
      date = toStringDate(date)
      if (baseExports.isDate(date)) {
        var result = format || setupDefaults.formatString
        var hours = date.getHours()
        var apm = hours < 12 ? 'am' : 'pm'
        var zoneHours = date.getTimezoneOffset() / 60 * -1
        var formats = baseExports.assign({}, setupDefaults.formatStringMatchs, options ? options.formats : null)
        var timeRules = [
          [/y{2,4}/g, '', function (match) { return ('' + _dateFullYear(date)).substr(4 - match.length) }],
          [/M{1,2}/g, _dateMonth(date) + 1],
          [/d{1,2}/g, date.getDate()],
          [/H{1,2}/g, hours],
          [/h{1,2}/g, hours <= 12 ? hours : hours - 12],
          [/m{1,2}/g, date.getMinutes()],
          [/s{1,2}/g, date.getSeconds()],
          [/S{1,3}/g, date.getMilliseconds()],
          [/a/g, '', function (match) { return handleCustomTemplate(date, formats, match, apm) }],
          [/A/g, '', function (match) { return handleCustomTemplate(date, formats, match, apm.toLocaleUpperCase()) }],
          [/e/g, '', function (match) { return handleCustomTemplate(date, formats, match, date.getDay() - 1) }],
          [/E/g, '', function (match) { return handleCustomTemplate(date, formats, match, date.getDay()) }],
          [/q/g, '', function (match) { return handleCustomTemplate(date, formats, match, Math.floor((_dateMonth(date) + 3) / 3)) }],
          [/Z{1,2}/g, '', function (match) { return handleCustomTemplate(date, formats, match, (zoneHours >= 0 ? '+' : '-') + formatPadStart(zoneHours, 2, '0') + (match.length === 1 ? ':' : '') + '00') }],
          [/W{1,2}/g, '', function (match) { return formatPadStart(handleCustomTemplate(date, formats, match, getYearWeek(date)), match.length, '0') }],
          [/D{1,3}/g, '', function (match) { return formatPadStart(handleCustomTemplate(date, formats, match, getYearDay(date)), match.length, '0') }]
        ]
        var item
        var index = 0
        var len = timeRules.length
        for (; index < len; index++) {
          item = timeRules[index]
          result = result.replace(item[0], item[2] || function (match) {
            return formatPadStart(item[1], match.length, '0')
          })
        }
        return result
      }
      return date
    }
    return ''
  }