fix: escape last period to match only milliseconds (#1239)
fix #1239
To be sure the last digit token in REGEX_PARSE only matches for milliseconds, the period must be escaped. Otherwise, it acts as a wildcard.

All of these are the same date/time using different ISO 8601 time zone formats:
`dayjs("2020-12-31T18:00:00.000-0500")`
`dayjs("2020-12-31T18:00:00-05:00")`
`dayjs("2020-12-31T18:00:00-0500")`
The first two parse correctly because REGEX_PARSE doesn't match. But the last example does match REGEX_PARSE, with the final `-` character matching the wildcard. So the date is parsed in local time and the first three characters of 0500 become 50ms.
**Describe the bug**
`dayjs.utc('2020-12-01T09:00:00+0900').toDate().getTime() ===  new Date('2020-12-01T09:00:00+0900').getTime()`

**Expected behavior**
The above evaluates to true. It's the behaviour of dayjs 1.8.33.

**Actual behaviour**
```
> dayjs.utc('2020-12-01T09:00:00+0900').toDate()
2020-12-01T09:00:00.090Z
> new Date('2020-12-01T00:00:00+0900')
2020-11-30T15:00:00.000Z
```

**Information**
 - Day.js Version: 1.9.6
 - OS: macOS
 - Browser: 
 - Time zone: GMT+0900 (Korean Standard Time)

dayjs.utc() dropped timezone offset support
diff --git a/src/constant.js b/src/constant.js
index 22c1319e0..875ef02b4 100644
--- 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+)?$/
+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{1,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/test/parse.test.js b/test/parse.test.js
index aecbaa898..501e213df 100644
--- a/test/parse.test.js
+++ b/test/parse.test.js
@@ -148,4 +148,34 @@ describe('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')
   })
+  it('20210102T012345', () => {
+    const date = '20210102T012345'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d.join('-')).toBe('20210102T012345-2021-01-02-01-23-45-')
+  })
+  it('2021-01-02T01:23', () => {
+    const date = '2021-01-02T01:23'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d.join('-')).toBe('2021-01-02T01:23-2021-01-02-01-23--')
+  })
+  it('2021-01-02T01:23:45', () => {
+    const date = '2021-01-02T01:23:45'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d.join('-')).toBe('2021-01-02T01:23:45-2021-01-02-01-23-45-')
+  })
+  it('2021-01-02T01:23:45-0500 (no regex match)', () => {
+    const date = '2021-01-02T01:23:45-0500'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d).toBe(null)
+  })
+  it('2021-01-02T01:23:45Z (no regex match)', () => {
+    const date = '2021-01-02T01:23:45Z'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d).toBe(null)
+  })
 })

{"test/parse.test.js": {"run": "PASS", "test": "FAIL", "fix": "PASS"}}
{"test/timezone.test.js:Add Time days (DST)": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/de.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/sk.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/timezone.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isSameOrBefore.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/pluralGetSet.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:Diff (DST)": {"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/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/isLeapYear.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/timezone.test.js:UTC diff in DST": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/zh.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/declarations.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/timezone.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/ru.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/dayOfYear.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:UTC add day in DST": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/manipulate.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/cs.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/en.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/he.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/plugin/objectSupport.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/fi.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/sv.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/toArray.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:Utc Offset": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/utc-utcOffset.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/sr-cyrl.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/br.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/locale/sr.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/comparison.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isTomorrow.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/hu.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/et.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/calendar.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/timezone.test.js:UTC and utcOffset": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/arraySupport.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isToday.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/hr.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/plugin/customParseFormat.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/duration.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isoWeek.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/minMax.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isoWeeksInYear.test.js": {"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/display.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/lt.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/locale/zh-cn.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}, "test/plugin/isBetween.test.js": {"run": "PASS", "test": "PASS", "fix": "PASS"}}
{"test/parse.test.js": {"run": "PASS", "test": "FAIL", "fix": "PASS"}}
{"passed_count": 72, "failed_count": 0, "skipped_count": 0, "passed_tests": ["test/timezone.test.js:Add Time days (DST)", "test/locale/de.test.js", "test/locale/he.test.js", "test/plugin.test.js", "test/get-set.test.js", "test/plugin/utc.test.js", "test/plugin/quarterOfYear.test.js", "test/plugin/objectSupport.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/plugin/pluralGetSet.test.js", "test/timezone.test.js:Diff (DST)", "test/plugin/utc-utcOffset.test.js", "test/locale/sr-cyrl.test.js", "test/utils.test.js", "test/locale/br.test.js", "test/plugin/relativeTime.test.js", "test/parse.test.js", "test/locale/keys.test.js", "test/plugin/isMoment.test.js", "test/plugin/isYesterday.test.js", "test/locale/pl.test.js", "test/plugin/toObject.test.js", "test/locale/sr.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/locale/hu.test.js", "test/locale/et.test.js", "test/timezone.test.js:UTC diff in DST", "test/plugin/calendar.test.js", "test/timezone.test.js:UTC and utcOffset", "test/plugin/arraySupport.test.js", "test/locale/zh.test.js", "test/plugin/isToday.test.js", "test/plugin/declarations.test.js", "test/locale/hr.test.js", "test/plugin/timezone.test.js", "test/locale.test.js", "test/plugin/badMutable.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/manipulate.test.js", "test/locale/cs.test.js", "test/locale/uk.test.js", "test/display.test.js", "test/locale/lt.test.js", "test/locale/zh-cn.test.js", "test/locale/en.test.js", "test/plugin/isBetween.test.js"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 71, "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/locale/he.test.js", "test/locale/de.test.js", "test/plugin/utc.test.js", "test/plugin/quarterOfYear.test.js", "test/plugin/objectSupport.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/plugin/pluralGetSet.test.js", "test/timezone.test.js:Diff (DST)", "test/plugin/utc-utcOffset.test.js", "test/locale/sr-cyrl.test.js", "test/locale/br.test.js", "test/utils.test.js", "test/plugin/relativeTime.test.js", "test/locale/keys.test.js", "test/plugin/isMoment.test.js", "test/plugin/isYesterday.test.js", "test/locale/pl.test.js", "test/plugin/toObject.test.js", "test/locale/sr.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/comparison.test.js", "test/plugin/isLeapYear.test.js", "test/query.test.js", "test/plugin/localeData.test.js", "test/locale/et.test.js", "test/plugin/isTomorrow.test.js", "test/plugin/calendar.test.js", "test/timezone.test.js:UTC diff in DST", "test/locale/hu.test.js", "test/timezone.test.js:UTC and utcOffset", "test/plugin/arraySupport.test.js", "test/locale/zh.test.js", "test/plugin/isToday.test.js", "test/plugin/declarations.test.js", "test/locale/hr.test.js", "test/plugin/timezone.test.js", "test/locale.test.js", "test/plugin/badMutable.test.js", "test/plugin/customParseFormat.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/locale/uk.test.js", "test/display.test.js", "test/plugin/buddhistEra.test.js", "test/locale/cs.test.js", "test/locale/lt.test.js", "test/locale/zh-cn.test.js", "test/locale/en.test.js", "test/plugin/isBetween.test.js"], "failed_tests": ["test/parse.test.js"], "skipped_tests": []}
{"passed_count": 72, "failed_count": 0, "skipped_count": 0, "passed_tests": ["test/timezone.test.js:Add Time days (DST)", "test/plugin.test.js", "test/get-set.test.js", "test/locale/de.test.js", "test/locale/he.test.js", "test/plugin/utc.test.js", "test/plugin/quarterOfYear.test.js", "test/plugin/objectSupport.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/plugin/isSameOrBefore.test.js", "test/timezone.test.js:Utc Offset", "test/plugin/pluralGetSet.test.js", "test/timezone.test.js:Diff (DST)", "test/plugin/utc-utcOffset.test.js", "test/locale/sr-cyrl.test.js", "test/locale/br.test.js", "test/utils.test.js", "test/plugin/relativeTime.test.js", "test/parse.test.js", "test/locale/keys.test.js", "test/plugin/isMoment.test.js", "test/plugin/isYesterday.test.js", "test/locale/pl.test.js", "test/plugin/toObject.test.js", "test/locale/sr.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/locale/et.test.js", "test/plugin/calendar.test.js", "test/plugin/isTomorrow.test.js", "test/timezone.test.js:UTC diff in DST", "test/locale/hu.test.js", "test/timezone.test.js:UTC and utcOffset", "test/plugin/arraySupport.test.js", "test/locale/zh.test.js", "test/plugin/isToday.test.js", "test/plugin/declarations.test.js", "test/locale/hr.test.js", "test/plugin/timezone.test.js", "test/locale.test.js", "test/plugin/badMutable.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/locale/uk.test.js", "test/plugin/buddhistEra.test.js", "test/locale/cs.test.js", "test/manipulate.test.js", "test/display.test.js", "test/locale/lt.test.js", "test/locale/zh-cn.test.js", "test/locale/en.test.js", "test/plugin/isBetween.test.js"], "failed_tests": [], "skipped_tests": []}