fix: Update CustomParseFormat plugin strict mode
fix #881
**Describe the bug**
Inconsistencies where `0` is involved

For example:

```javascript
const m1 = dayjs('1970-07-05', 'YYYY-MM-DD').format('DD-MM-YYYY') // '05-07-1970'

assert(dayjs('1970-00-00', 'YYYY-MM-DD').isValid(), "should this be valid?")

const  m2 = dayjs('1970-00-00', 'YYYY-MM-DD').format('DD-MM-YYYY') // '30-11-1969'

const m3 = dayjs('0000-01-01', 'YYYY-MM-DD').format('DD-MM-YYYY') // '01-01-1900'
```

**Expected behavior**
I was surprised that this code was true

```
assert(dayjs('1970-00-00', 'YYYY-MM-DD').isValid(), "should this be valid?")
```

Is this a bug or expected behaviour?

**Information**
version - 1.8.23
os - osx
inconsistencies where 0 is involved when initialising from a string
diff --git a/src/index.js b/src/index.js
index f71f97f79..ebfad144c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -28,13 +28,14 @@ const parseLocale = (preset, object, isLocal) => {
   return l || (!isLocal && L)
 }
 
-const dayjs = (date, c, pl) => {
+const dayjs = function (date, c) {
   if (isDayjs(date)) {
     return date.clone()
   }
   // eslint-disable-next-line no-nested-ternary
-  const cfg = c ? (typeof c === 'string' ? { format: c, pl } : c) : {}
+  const cfg = typeof c === 'object' ? c : {}
   cfg.date = date
+  cfg.args = arguments// eslint-disable-line prefer-rest-params
   return new Dayjs(cfg) // eslint-disable-line no-use-before-define
 }
 
diff --git a/src/plugin/customParseFormat/index.js b/src/plugin/customParseFormat/index.js
index 6d754f105..850c0483c 100644
--- a/src/plugin/customParseFormat/index.js
+++ b/src/plugin/customParseFormat/index.js
@@ -181,16 +181,26 @@ export default (o, C, d) => {
   proto.parse = function (cfg) {
     const {
       date,
-      format,
-      pl,
-      utc
+      utc,
+      args
     } = cfg
     this.$u = utc
-    if (format) {
-      locale = pl ? d.Ls[pl] : this.$locale()
+    const format = args[1]
+    if (typeof format === 'string') {
+      const isStrictWithoutLocale = args[2] === true
+      const isStrictWithLocale = args[3] === true
+      const isStrict = isStrictWithoutLocale || isStrictWithLocale
+      let pl = args[2]
+      if (isStrictWithLocale) [,, pl] = args
+      if (!isStrictWithoutLocale) {
+        locale = pl ? d.Ls[pl] : this.$locale()
+      }
       this.$d = parseFormattedInput(date, format, utc)
       this.init(cfg)
-      if (pl) this.$L = pl
+      if (isStrict && date !== this.format(format)) {
+        this.$d = new Date('')
+      }
+      if (pl && pl !== true) this.$L = pl
     } else {
       oldParse.call(this, cfg)
     }
diff --git a/src/plugin/utc/index.js b/src/plugin/utc/index.js
index 606a831a2..a5bc6353f 100644
--- a/src/plugin/utc/index.js
+++ b/src/plugin/utc/index.js
@@ -3,8 +3,8 @@ import { MILLISECONDS_A_MINUTE, MIN } from '../../constant'
 export default (option, Dayjs, dayjs) => {
   const localOffset = (new Date()).getTimezoneOffset()
   const proto = Dayjs.prototype
-  dayjs.utc = function (date, format) {
-    const cfg = { date, utc: true, format }
+  dayjs.utc = function (date) {
+    const cfg = { date, utc: true, args: arguments } // eslint-disable-line prefer-rest-params
     return new Dayjs(cfg) // eslint-disable-line no-use-before-define
   }
 

diff --git a/test/plugin/customParseFormat.test.js b/test/plugin/customParseFormat.test.js
index c73377053..0e0260315 100644
--- a/test/plugin/customParseFormat.test.js
+++ b/test/plugin/customParseFormat.test.js
@@ -146,13 +146,13 @@ it('parse month from string with locale in config', () => {
   const input = '2018 лютий 03'
   const format = 'YYYY MMMM DD'
 
-  expect(dayjs(input, { format, locale: uk }).valueOf()).toBe(moment(input, format, 'uk').valueOf())
+  expect(dayjs(input, format, 'uk').valueOf()).toBe(moment(input, format, 'uk').valueOf())
 })
 
 it('parse month from short string with locale in config', () => {
   const input = '2018 трав 03'
   const format = 'YYYY MMM DD'
-  expect(dayjs(input, { format, locale: uk }).valueOf()).toBe(moment(input, format, 'uk').valueOf())
+  expect(dayjs(input, format, 'uk').valueOf()).toBe(moment(input, format, 'uk').valueOf())
 })
 
 it('parse month from short string with locale in argument', () => {
@@ -232,3 +232,19 @@ it('correctly parse ordinal', () => {
   expect(dayjsCN.locale())
     .toBe(momentCN.locale())
 })
+
+
+describe('Strict mode', () => {
+  it('without locale', () => {
+    const input = '1970-00-00'
+    const format = 'YYYY-MM-DD'
+    expect(dayjs(input, format).isValid()).toBe(true)
+    expect(dayjs(input, format, true).isValid()).toBe(false)
+  })
+  it('with locale', () => {
+    const input = '2018 三月 99'
+    const format = 'YYYY MMMM DD'
+    expect(dayjs(input, format, 'zh-cn').isValid()).toBe(true)
+    expect(dayjs(input, format, 'zh-cn', true).isValid()).toBe(false)
+  })
+})
diff --git a/test/plugin/isoWeek.test.js b/test/plugin/isoWeek.test.js
index 8c2157f2f..b86a6d6ae 100644
--- a/test/plugin/isoWeek.test.js
+++ b/test/plugin/isoWeek.test.js
@@ -38,6 +38,7 @@ it('isoWeekday', () => {
   for (let i = 0; i < 7; i += 1) {
     expect(dayjs().add(i, 'day').isoWeekday()).toBe(moment().add(i, 'day').isoWeekday())
     expect(dayjs().isoWeekday(i).valueOf()).toBe(moment().isoWeekday(i).valueOf())
+    expect(dayjs().add(1, 'day').isoWeekday(i).valueOf()).toBe(moment().add(1, 'day').isoWeekday(i).valueOf())
   }
 })
 

{"test/plugin/customParseFormat.test.js": {"run": "PASS", "test": "FAIL", "fix": "PASS"}}
{"test/timezone.test.js:Add Time days (DST)": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/get-set.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/utc.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/quarterOfYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/fi.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/sk.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/sv.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/advancedFormat.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/weekYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/toArray.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:Utc Offset": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isSameOrBefore.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:Diff (DST)": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/utc-utcOffset.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/keys.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/utils.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/relativeTime.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/parse.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isMoment.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isYesterday.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/pl.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/toObject.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/localizedFormat.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/updateLocale.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/constructor.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/weekday.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isSameOrAfter.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/weekOfYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isLeapYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/comparison.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/query.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/localeData.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isTomorrow.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/calendar.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/et.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/zh.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isToday.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/declarations.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/badMutable.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/ru.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isoWeek.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/duration.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/minMax.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/dayOfYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isoWeeksInYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:UTC add day in DST": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/buddhistEra.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/uk.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/cs.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/manipulate.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/zh-cn.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/en.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isBetween.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}}
{"test/plugin/customParseFormat.test.js": {"run": "PASS", "test": "FAIL", "fix": "PASS"}}
{"passed_count": 57, "failed_count": 1, "skipped_count": 0, "passed_tests": ["test/timezone.test.js:Add Time days (DST)", "test/plugin.test.js", "test/get-set.test.js", "test/plugin/utc.test.js", "test/plugin/quarterOfYear.test.js", "test/locale/fi.test.js", "test/locale/sk.test.js", "test/locale/sv.test.js", "test/plugin/advancedFormat.test.js", "test/plugin/weekYear.test.js", "test/plugin/toArray.test.js", "test/timezone.test.js", "test/timezone.test.js:Utc Offset", "test/plugin/isSameOrBefore.test.js", "test/timezone.test.js:Diff (DST)", "test/plugin/utc-utcOffset.test.js", "test/locale/keys.test.js", "test/utils.test.js", "test/plugin/relativeTime.test.js", "test/parse.test.js", "test/plugin/isMoment.test.js", "test/plugin/isYesterday.test.js", "test/locale/pl.test.js", "test/plugin/toObject.test.js", "test/plugin/localizedFormat.test.js", "test/plugin/updateLocale.test.js", "test/constructor.test.js", "test/plugin/weekday.test.js", "test/plugin/isSameOrAfter.test.js", "test/plugin/weekOfYear.test.js", "test/plugin/isLeapYear.test.js", "test/comparison.test.js", "test/query.test.js", "test/plugin/localeData.test.js", "test/plugin/isTomorrow.test.js", "test/plugin/calendar.test.js", "test/locale/et.test.js", "test/locale/zh.test.js", "test/plugin/isToday.test.js", "test/plugin/declarations.test.js", "test/locale.test.js", "test/plugin/badMutable.test.js", "test/plugin/customParseFormat.test.js", "test/locale/ru.test.js", "test/plugin/isoWeek.test.js", "test/plugin/duration.test.js", "test/plugin/minMax.test.js", "test/plugin/dayOfYear.test.js", "test/plugin/isoWeeksInYear.test.js", "test/timezone.test.js:UTC add day in DST", "test/plugin/buddhistEra.test.js", "test/locale/uk.test.js", "test/locale/cs.test.js", "test/manipulate.test.js", "test/locale/zh-cn.test.js", "test/locale/en.test.js", "test/plugin/isBetween.test.js"], "failed_tests": ["test/display.test.js"], "skipped_tests": []}
{"passed_count": 56, "failed_count": 2, "skipped_count": 0, "passed_tests": ["test/timezone.test.js:Add Time days (DST)", "test/get-set.test.js", "test/plugin.test.js", "test/plugin/utc.test.js", "test/plugin/quarterOfYear.test.js", "test/locale/fi.test.js", "test/locale/sk.test.js", "test/locale/sv.test.js", "test/plugin/advancedFormat.test.js", "test/plugin/weekYear.test.js", "test/plugin/toArray.test.js", "test/timezone.test.js", "test/timezone.test.js:Utc Offset", "test/plugin/isSameOrBefore.test.js", "test/timezone.test.js:Diff (DST)", "test/plugin/utc-utcOffset.test.js", "test/locale/keys.test.js", "test/utils.test.js", "test/plugin/relativeTime.test.js", "test/parse.test.js", "test/plugin/isMoment.test.js", "test/plugin/isYesterday.test.js", "test/locale/pl.test.js", "test/plugin/toObject.test.js", "test/plugin/localizedFormat.test.js", "test/plugin/updateLocale.test.js", "test/constructor.test.js", "test/plugin/weekday.test.js", "test/plugin/isSameOrAfter.test.js", "test/plugin/weekOfYear.test.js", "test/plugin/isLeapYear.test.js", "test/comparison.test.js", "test/query.test.js", "test/plugin/localeData.test.js", "test/plugin/calendar.test.js", "test/plugin/isTomorrow.test.js", "test/locale/et.test.js", "test/locale/zh.test.js", "test/plugin/isToday.test.js", "test/plugin/declarations.test.js", "test/locale.test.js", "test/plugin/badMutable.test.js", "test/locale/ru.test.js", "test/plugin/duration.test.js", "test/plugin/isoWeek.test.js", "test/plugin/minMax.test.js", "test/plugin/dayOfYear.test.js", "test/plugin/isoWeeksInYear.test.js", "test/timezone.test.js:UTC add day in DST", "test/manipulate.test.js", "test/plugin/buddhistEra.test.js", "test/locale/cs.test.js", "test/locale/uk.test.js", "test/locale/zh-cn.test.js", "test/locale/en.test.js", "test/plugin/isBetween.test.js"], "failed_tests": ["test/plugin/customParseFormat.test.js", "test/display.test.js"], "skipped_tests": []}
{"passed_count": 57, "failed_count": 1, "skipped_count": 0, "passed_tests": ["test/timezone.test.js:Add Time days (DST)", "test/get-set.test.js", "test/plugin.test.js", "test/plugin/utc.test.js", "test/plugin/quarterOfYear.test.js", "test/locale/fi.test.js", "test/locale/sk.test.js", "test/locale/sv.test.js", "test/plugin/advancedFormat.test.js", "test/plugin/toArray.test.js", "test/plugin/weekYear.test.js", "test/timezone.test.js", "test/timezone.test.js:Utc Offset", "test/plugin/isSameOrBefore.test.js", "test/timezone.test.js:Diff (DST)", "test/plugin/utc-utcOffset.test.js", "test/locale/keys.test.js", "test/utils.test.js", "test/plugin/relativeTime.test.js", "test/parse.test.js", "test/plugin/isMoment.test.js", "test/plugin/isYesterday.test.js", "test/locale/pl.test.js", "test/plugin/toObject.test.js", "test/plugin/localizedFormat.test.js", "test/plugin/updateLocale.test.js", "test/constructor.test.js", "test/plugin/weekday.test.js", "test/plugin/isSameOrAfter.test.js", "test/plugin/weekOfYear.test.js", "test/plugin/isLeapYear.test.js", "test/comparison.test.js", "test/query.test.js", "test/plugin/localeData.test.js", "test/plugin/isTomorrow.test.js", "test/plugin/calendar.test.js", "test/locale/et.test.js", "test/locale/zh.test.js", "test/plugin/isToday.test.js", "test/plugin/declarations.test.js", "test/plugin/badMutable.test.js", "test/locale.test.js", "test/plugin/customParseFormat.test.js", "test/locale/ru.test.js", "test/plugin/duration.test.js", "test/plugin/isoWeek.test.js", "test/plugin/dayOfYear.test.js", "test/plugin/minMax.test.js", "test/plugin/isoWeeksInYear.test.js", "test/timezone.test.js:UTC add day in DST", "test/plugin/buddhistEra.test.js", "test/locale/uk.test.js", "test/locale/cs.test.js", "test/manipulate.test.js", "test/locale/zh-cn.test.js", "test/locale/en.test.js", "test/plugin/isBetween.test.js"], "failed_tests": ["test/display.test.js"], "skipped_tests": []}