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/duration/index.js b/src/plugin/duration/index.js
--- a/src/plugin/duration/index.js
+++ b/src/plugin/duration/index.js
@@ -95,7 +95,7 @@ class Duration {
       seconds += this.$d.milliseconds / 1000
     }
     const S = seconds ? `${seconds}S` : ''
-    const T = (H || M || S) ? 'T' : ''
+    const T = (H || m || S) ? 'T' : ''
     const result = `P${Y}${M}${D}${T}${H}${m}${S}`
     return result === 'P' ? 'P0D' : result
   }
diff --git a/src/plugin/relativeTime/index.js b/src/plugin/relativeTime/index.js
--- a/src/plugin/relativeTime/index.js
+++ b/src/plugin/relativeTime/index.js
@@ -3,7 +3,7 @@ import * as C from '../../constant'
 export default (o, c, d) => {
   o = o || {}
   const proto = c.prototype
-  d.en.relativeTime = {
+  const relObj = {
     future: 'in %s',
     past: '%s ago',
     s: 'a few seconds',
@@ -18,8 +18,9 @@ export default (o, c, d) => {
     y: 'a year',
     yy: '%d years'
   }
+  d.en.relativeTime = relObj
   const fromTo = (input, withoutSuffix, instance, isFrom) => {
-    const loc = instance.$locale().relativeTime
+    const loc = instance.$locale().relativeTime || relObj
     const T = o.thresholds || [
       { l: 's', r: 44, d: C.S },
       { l: 'm', r: 89 },
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/src/plugin/weekOfYear/index.js b/src/plugin/weekOfYear/index.js
--- a/src/plugin/weekOfYear/index.js
+++ b/src/plugin/weekOfYear/index.js
@@ -1,6 +1,6 @@
 import { MS, Y, D, W } from '../../constant'
 
-export default (o, c) => {
+export default (o, c, d) => {
   const proto = c.prototype
   proto.week = function (week = null) {
     if (week !== null) {
@@ -8,17 +8,18 @@ export default (o, c) => {
     }
     const yearStart = this.$locale().yearStart || 1
     if (this.month() === 11 && this.date() > 25) {
-      const nextYearStartDay = this.startOf(Y).add(1, Y).date(yearStart)
-      const thisEndOfWeek = this.endOf(W)
+      // d(this) is for badMutable
+      const nextYearStartDay = d(this).startOf(Y).add(1, Y).date(yearStart)
+      const thisEndOfWeek = d(this).endOf(W)
       if (nextYearStartDay.isBefore(thisEndOfWeek)) {
         return 1
       }
     }
-    const yearStartDay = this.startOf(Y).date(yearStart)
+    const yearStartDay = d(this).startOf(Y).date(yearStart)
     const yearStartWeek = yearStartDay.startOf(W).subtract(1, MS)
     const diffInWeek = this.diff(yearStartWeek, W, true)
     if (diffInWeek < 0) {
-      return this.startOf('week').week()
+      return d(this).startOf('week').week()
     }
     return Math.ceil(diffInWeek)
   }

diff --git a/test/plugin/badMutable.test.js b/test/plugin/badMutable.test.js
--- a/test/plugin/badMutable.test.js
+++ b/test/plugin/badMutable.test.js
@@ -2,9 +2,11 @@ import MockDate from 'mockdate'
 import moment from 'moment'
 import dayjs from '../../src'
 import badMutable from '../../src/plugin/badMutable'
+import weekOfYear from '../../src/plugin/weekOfYear'
 import '../../src/locale/zh-cn'
 
 dayjs.extend(badMutable)
+dayjs.extend(weekOfYear)
 
 beforeEach(() => {
   MockDate.set(new Date())
@@ -175,3 +177,10 @@ it('isAfter isBefore isSame', () => {
   expect(d.format()).toBe(format)
   expect(d.isAfter()).toBe(false)
 })
+
+it('WeekOfYear get week won"t change instance', () => {
+  const d = dayjs()
+  const format = d.format()
+  d.week()
+  expect(d.format()).toBe(format)
+})
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/duration.test.js b/test/plugin/duration.test.js
--- a/test/plugin/duration.test.js
+++ b/test/plugin/duration.test.js
@@ -23,7 +23,7 @@ describe('Creating', () => {
   })
   it('two argument will bubble up to the next', () => {
     expect(dayjs.duration(59, 'seconds').toISOString()).toBe('PT59S')
-    expect(dayjs.duration(60, 'seconds').toISOString()).toBe('P1M')
+    expect(dayjs.duration(60, 'seconds').toISOString()).toBe('PT1M')
     expect(dayjs.duration(13213, 'seconds').toISOString()).toBe('PT3H40M13S')
   })
   it('object with float', () => {
@@ -78,7 +78,7 @@ it('Is duration', () => {
 it('toJSON', () => {
   expect(JSON.stringify({
     postDuration: dayjs.duration(5, 'minutes')
-  })).toBe('{"postDuration":"P5M"}')
+  })).toBe('{"postDuration":"PT5M"}')
 })
 
 describe('Humanize', () => {
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())
   }
 })
 
diff --git a/test/plugin/relativeTime.test.js b/test/plugin/relativeTime.test.js
--- a/test/plugin/relativeTime.test.js
+++ b/test/plugin/relativeTime.test.js
@@ -137,3 +137,9 @@ it('Custom thresholds and rounding support', () => {
   })
   expect(dayjs().subtract(45, 'm').fromNow()).toBe('45 minutes ago')
 })
+
+it('Locale without relativeTime config fallback', () => {
+  expect(dayjs().locale({
+    name: 'test-locale'
+  }).fromNow()).toEqual(expect.any(String))
+})

Duration.toISOString() returns wrong result
**Describe the bug**
dayjs.duration(dayjs.duration(1, 'minutes').toISOString()).as('minutes') returns 43200
dayjs.duration(1, 'minutes').toISOString() return 'P1M'

**Expected behavior**
Should return 1
Suppose that dayjs.duration(1, 'minutes').toISOString() should return 'PT1M'

**Information**
 - Day.js Version [1.8.24]
 - OS: [macOS Mojave 10.14.6]
 - Browser [chrome 81.0.4044.122 (Official Build) (64-bit)]
 - Time zone: [GMT+3 (Moscow Standard Time)]


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/badMutable.test.js test/plugin/relativeTime.test.js test/plugin/duration.test.js test/plugin/customParseFormat.test.js