diff --git a/src/constant.js b/src/constant.js
--- a/src/constant.js
+++ b/src/constant.js
@@ -26,5 +26,5 @@ export const FORMAT_DEFAULT = 'YYYY-MM-DDTHH:mm:ssZ'
 export const INVALID_DATE_STRING = 'Invalid Date'
 
 // regex
-export const REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d{1,3})?$/
+export const REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d+)?$/
 export const REGEX_FORMAT = /\[([^\]]+)]|Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g
diff --git a/src/index.js b/src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -60,12 +60,13 @@ const parseDate = (cfg) => {
     const d = date.match(C.REGEX_PARSE)
     if (d) {
       const m = d[2] - 1 || 0
+      const ms = (d[7] || '0').substring(0, 3)
       if (utc) {
         return new Date(Date.UTC(d[1], m, d[3]
-          || 1, d[4] || 0, d[5] || 0, d[6] || 0, d[7] || 0))
+          || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms))
       }
       return new Date(d[1], m, d[3]
-          || 1, d[4] || 0, d[5] || 0, d[6] || 0, d[7] || 0)
+          || 1, d[4] || 0, d[5] || 0, d[6] || 0, 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
@@ -28,7 +28,7 @@ const prettyUnit = unit => `${$u.p(unit)}s`
 class Duration {
   constructor(input, unit, locale) {
     this.$d = {}
-    this.$l = locale || 'en'
+    this.$l = locale
     if (unit) {
       return wrapper(input * unitToMS[prettyUnit(unit)], this)
     }
@@ -172,7 +172,8 @@ export default (option, Dayjs, dayjs) => {
   $d = dayjs
   $u = dayjs().$utils()
   dayjs.duration = function (input, unit) {
-    return wrapper(input, {}, unit)
+    const $l = dayjs.locale()
+    return wrapper(input, { $l }, unit)
   }
   dayjs.isDuration = isDuration
 }
diff --git a/src/plugin/timezone/index.js b/src/plugin/timezone/index.js
--- a/src/plugin/timezone/index.js
+++ b/src/plugin/timezone/index.js
@@ -7,6 +7,8 @@ const typeToPos = {
   second: 5
 }
 
+const ms = 'ms'
+
 export default (o, c, d) => {
   const localUtcOffset = d().utcOffset()
   const tzOffset = (timestamp, timezone) => {
@@ -55,7 +57,7 @@ export default (o, c, d) => {
   proto.tz = function (timezone) {
     const target = this.toDate().toLocaleString('en-US', { timeZone: timezone })
     const diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60)
-    return d(target).utcOffset(localUtcOffset - diff, true)
+    return d(target).utcOffset(localUtcOffset - diff, true).$set(ms, this.$ms)
   }
   d.tz = function (input, timezone) {
     const previousOffset = tzOffset(+d(), timezone)

diff --git a/test/parse.test.js b/test/parse.test.js
--- a/test/parse.test.js
+++ b/test/parse.test.js
@@ -81,6 +81,14 @@ describe('Parse', () => {
     expect(normalized.toISOString()).toEqual(expected)
   })
 
+  it('parses unlimited millisecond', () => {
+    const date = '2019-03-25T06:41:00.999999999'
+    const ds = dayjs(date)
+    const ms = moment(date)
+    expect(ds.valueOf()).toEqual(ms.valueOf())
+    expect(ds.millisecond()).toEqual(ms.millisecond())
+  })
+
   it('String Other, Null and isValid', () => {
     global.console.warn = jest.genMockFunction()// moment.js otherString will throw warn
     expect(dayjs('otherString').toString().toLowerCase()).toBe(moment('otherString').toString().toLowerCase())
@@ -134,4 +142,10 @@ describe('REGEX_PARSE', () => {
     expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
     expect(d.join('-')).toBe('2020/9/30-2020-9-30----')
   })
+  it('2019-03-25T06:41:00.999999999', () => {
+    const date = '2019-03-25T06:41:00.999999999'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d.join('-')).toBe('2019-03-25T06:41:00.999999999-2019-03-25-06-41-00-999999999')
+  })
 })
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
@@ -101,6 +101,15 @@ describe('Humanize', () => {
     expect(dayjs.duration(1, 'minutes').locale('fr').humanize(true)).toBe('dans une minute')
     expect(dayjs.duration(1, 'minutes').locale('es').humanize(true)).toBe('en un minuto')
   })
+  it('Global Locale', () => {
+    dayjs.locale('en')
+    expect(dayjs.duration(1, 'minutes').humanize(true)).toBe('in a minute')
+    dayjs.locale('fr')
+    expect(dayjs.duration(1, 'minutes').humanize(true)).toBe('dans une minute')
+    dayjs.locale('es')
+    expect(dayjs.duration(1, 'minutes').humanize(true)).toBe('en un minuto')
+    dayjs.locale('en')
+  })
 })
 
 describe('Clone', () => {
diff --git a/test/plugin/timezone.test.js b/test/plugin/timezone.test.js
--- a/test/plugin/timezone.test.js
+++ b/test/plugin/timezone.test.js
@@ -56,6 +56,14 @@ describe('Parse', () => {
     expect(newYork.tz('America/Los_Angeles').format()).toBe('2014-06-01T09:00:00-07:00')
     expect(newYork.tz('Europe/London').format()).toBe('2014-06-01T17:00:00+01:00')
   })
+
+  it('preserve milliseconds', () => {
+    const d = dayjs(1596735327399)
+    const oldMs = d.millisecond()
+    const dTz = d.tz('America/New_York')
+    const newMs = dTz.millisecond()
+    expect(oldMs).toEqual(newMs)
+  })
 })
 
 describe('Convert', () => {
diff --git a/test/plugin/utc.test.js b/test/plugin/utc.test.js
--- a/test/plugin/utc.test.js
+++ b/test/plugin/utc.test.js
@@ -54,7 +54,7 @@ describe('Parse UTC ', () => {
     expect(dayjs().utc().format()).toBe(moment().utc().format())
   })
 
-  it('Parse date string without timezome', () => {
+  it('Parse date string without timezone', () => {
     const d = '2018-09-06'
     expect(dayjs.utc(d).format()).toEqual(moment.utc(d).format())
     expect(dayjs.utc(d).format()).toEqual('2018-09-06T00:00:00Z')
@@ -76,7 +76,7 @@ describe('Parse UTC ', () => {
     expect(dayjs.utc(d2).format()).toEqual(moment.utc(d2).format())
   })
 
-  it('Parse date string without timezome', () => {
+  it('Parse date string without timezone', () => {
     const d = '2017-04-22 19:50:16'
     expect(dayjs.utc(d).format()).toEqual('2017-04-22T19:50:16Z')
     expect(dayjs.utc(d).format()).toEqual(moment.utc(d).format())
@@ -94,6 +94,14 @@ describe('Parse UTC ', () => {
     expect(dayjs.utc(d).format()).toEqual('2018-09-06T19:34:28Z')
     expect(dayjs.utc(d).format()).toEqual(moment.utc(d).format())
   })
+
+  it('parses unlimited millisecond in utc', () => {
+    const date = '2019-03-25T06:41:00.999999999'
+    const ds = dayjs.utc(date)
+    const ms = moment.utc(date)
+    expect(ds.valueOf()).toEqual(ms.valueOf())
+    expect(ds.millisecond()).toEqual(ms.millisecond())
+  })
 })
 
 it('Clone retains the UTC mode', () => {

dayjs.duration().humanize() international
My code:
```
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'
import relativeTime from 'dayjs/plugin/relativeTime'
import localeData from 'dayjs/plugin/localeData'

import 'dayjs/locale/zh-cn'

dayjs.extend(duration)
dayjs.extend(relativeTime)
dayjs.extend(localeData)

dayjs.locale('zh-cn')

dayjs.duration(24 * 60 * 60 * 1000).humanize() // return ' a day'
```
How to make "humanize()" return a Chinese string? I need your help, thanks.

test/timezone.test.js(1) test/timezone.test.js(2) test/timezone.test.js(3) test/timezone.test.js(4) test/plugin/utc.test.js
test/parse.test.js test/plugin/timezone.test.js test/plugin/duration.test.js