diff --git a/src/index.js b/src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -172,7 +172,7 @@ class Dayjs {
       const argumentStart = [0, 0, 0, 0]
       const argumentEnd = [23, 59, 59, 999]
       return Utils.w(this.toDate()[method].apply( // eslint-disable-line prefer-spread
-        this.toDate(),
+        this.toDate('s'),
         (isStartOf ? argumentStart : argumentEnd).slice(slice)
       ), this)
     }
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
@@ -151,21 +151,20 @@ const parseFormattedInput = (input, format, utc) => {
     const {
       year, month, day, hours, minutes, seconds, milliseconds, zone
     } = parser(input)
-    if (zone) {
-      return new Date(Date.UTC(
-        year, month - 1, day,
-        hours || 0,
-        minutes || 0, seconds || 0, milliseconds || 0
-      ) + (zone.offset * 60 * 1000))
-    }
     const now = new Date()
     const d = day || ((!year && !month) ? now.getDate() : 1)
     const y = year || now.getFullYear()
-    const M = month > 0 ? month - 1 : now.getMonth()
+    let M = 0
+    if (!(year && !month)) {
+      M = month > 0 ? month - 1 : now.getMonth()
+    }
     const h = hours || 0
     const m = minutes || 0
     const s = seconds || 0
     const ms = milliseconds || 0
+    if (zone) {
+      return new Date(Date.UTC(y, M, d, h, m, s, ms + (zone.offset * 60 * 1000)))
+    }
     if (utc) {
       return new Date(Date.UTC(y, M, d, h, m, s, ms))
     }
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
@@ -75,7 +75,9 @@ class Duration {
     $ms %= MILLISECONDS_A_HOUR
     this.$d.minutes = Math.floor($ms / MILLISECONDS_A_MINUTE)
     $ms %= MILLISECONDS_A_MINUTE
-    this.$d.seconds = $ms / MILLISECONDS_A_SECOND
+    this.$d.seconds = Math.floor($ms / MILLISECONDS_A_SECOND)
+    $ms %= MILLISECONDS_A_SECOND
+    this.$d.milliseconds = $ms
   }
 
   toISOString() {
@@ -111,8 +113,10 @@ class Duration {
     const pUnit = prettyUnit(unit)
     if (pUnit === 'milliseconds') {
       base %= 1000
-    } else {
+    } else if (pUnit === 'weeks') {
       base = Math.floor(base / unitToMS[pUnit])
+    } else {
+      base = this.$d[pUnit]
     }
     return base
   }
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
@@ -91,4 +91,12 @@ export default (option, Dayjs, dayjs) => {
   proto.toString = function () {
     return this.toDate().toUTCString()
   }
+
+  const oldToDate = proto.toDate
+  proto.toDate = function (type) {
+    if (type === 's' && this.$offset) {
+      return dayjs(this.format('YYYY-MM-DD HH:mm:ss:SSS')).toDate()
+    }
+    return oldToDate.call(this)
+  }
 }
diff --git a/types/index.d.ts b/types/index.d.ts
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -100,7 +100,7 @@ declare namespace dayjs {
 
   export function extend<T = unknown>(plugin: PluginFunc<T>, option?: T): Dayjs
 
-  export function locale(preset: string | ILocale, object?: Partial<ILocale>, isLocal?: boolean): string
+  export function locale(preset?: string | ILocale, object?: Partial<ILocale>, isLocal?: boolean): string
 
   export function isDayjs(d: any): d is Dayjs
 

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
@@ -98,6 +98,25 @@ it('parse HH:mm:ss but only one digit', () => {
   expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
 })
 
+describe('parse YYYY / YYYY-MM only', () => {
+  it('YYYY', () => {
+    const input = '2001 +08:00'
+    const format = 'YYYY Z'
+    expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
+    const input2 = '2001'
+    const format2 = 'YYYY'
+    expect(dayjs(input2, format2).valueOf()).toBe(moment(input2, format2).valueOf())
+  })
+  it('YYYY-MM', () => {
+    const input = '2001-01 +08:00'
+    const format = 'YYYY-MM Z'
+    expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
+    const input2 = '2001-01'
+    const format2 = 'YYYY-MM'
+    expect(dayjs(input2, format2).valueOf()).toBe(moment(input2, format2).valueOf())
+  })
+})
+
 it('parse hh:mm:ss but only one digit', () => {
   const input = '0:0:1'
   const format = 'hh:mm:ss'
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
@@ -134,6 +134,7 @@ describe('Seconds', () => {
   expect(dayjs.duration(500).seconds()).toBe(0)
   expect(dayjs.duration(1500).seconds()).toBe(1)
   expect(dayjs.duration(15000).seconds()).toBe(15)
+  expect(dayjs.duration(61000).seconds()).toBe(1) // 1 minute 1 second
   expect(dayjs.duration(500).asSeconds()).toBe(0.5)
   expect(dayjs.duration(1500).asSeconds()).toBe(1.5)
   expect(dayjs.duration(15000).asSeconds()).toBe(15)
@@ -141,6 +142,7 @@ describe('Seconds', () => {
 
 describe('Minutes', () => {
   expect(dayjs.duration(100000).minutes()).toBe(1)
+  expect(dayjs.duration(61000).minutes()).toBe(1) // 1 minute 1 second
   expect(dayjs.duration(100000).asMinutes().toFixed(2)).toBe('1.67')
 })
 
diff --git a/test/plugin/utc-utcOffset.test.js b/test/plugin/utc-utcOffset.test.js
--- a/test/plugin/utc-utcOffset.test.js
+++ b/test/plugin/utc-utcOffset.test.js
@@ -100,4 +100,11 @@ test('utc startOf', () => {
     .valueOf())
     .toBe(dayjs(d).utc().utcOffset(480).endOf('day')
       .valueOf())
+  const d2 = '2017-07-20T11:00:00+00:00'
+  const d2d = dayjs(d2).utcOffset(-12).startOf('day').valueOf()
+  const d2m = moment(d2).utcOffset(-12).startOf('day').valueOf()
+  expect(d2d)
+    .toBe(d2m)
+  expect(d2d)
+    .toBe(1500465600000)
 })

Format function with setted utcOffset does not work properly
**Describe the bug**
Format function with setted utcOffset does not work properly

**Expected behavior**

dayjs('2017-07-20T11:00:00+00:00').utcOffset(-12).format()

should equal to

moment('2017-07-20T11:00:00+00:00').utcOffset(-12).format()

and be '2017-07-19T23:00:00-12:00'

**Information**
 - Day.js Version v1.8.21
 - OS: Windows
 - Browser Chrome 80
 - Time zone: not zero


seems no problem.

https://runkit.com/embed/32nc6n1cn8s2

<img width="586" alt="Screen Shot 2020-02-29 at 1 06 41 PM" src="https://user-images.githubusercontent.com/17680888/75601243-5f8fc880-5af4-11ea-998d-e30f7185f161.png">

just use the same parameters, begin of day in your case with not zero local time:
https://runkit.com/embed/uhx3pxaltrns

I'm having a similar issue where:
moment.utc("2020-03-09T15:00:00.0000000Z").utcOffset(-360).format();
results in: 
2020-03-09T09:00:00-06:00
while:
dayjs.utc("2020-03-09T15:00:00.0000000Z").utcOffset(-360).format();
results in:
2020-03-09T10:00:00-06:00

https://runkit.com/humbertomendes/dayjs-utcoffset-issue
test/timezone.test.js(1) test/timezone.test.js(2) test/timezone.test.js(3) test/timezone.test.js(4)
test/plugin/utc-utcOffset.test.js test/plugin/customParseFormat.test.js test/plugin/duration.test.js