diff --git a/src/index.js b/src/index.js
--- 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
--- 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
--- 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
--- 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
--- 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())
   }
 })
 

inconsistencies where 0 is involved when initialising from a string
**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

This is valid to `new Date()`

We might need a strict mod to better handle this problem?
@iamkun just what I was going to suggest.  At least I know now though.  Thanks
test/timezone.test.js(1) test/timezone.test.js(2) test/timezone.test.js(3) test/timezone.test.js(4) test/plugin/isoWeek.test.js
test/plugin/customParseFormat.test.js