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+)?$/
+export const REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\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/src/index.js b/src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -251,11 +251,12 @@ class Dayjs {
   }
 
   format(formatStr) {
-    if (!this.isValid()) return C.INVALID_DATE_STRING
+    const locale = this.$locale()
+
+    if (!this.isValid()) return locale.invalidDate || C.INVALID_DATE_STRING
 
     const str = formatStr || C.FORMAT_DEFAULT
     const zoneStr = Utils.z(this)
-    const locale = this.$locale()
     const { $H, $m, $M } = this
     const {
       weekdays, months, meridiem
diff --git a/src/locale/bg.js b/src/locale/bg.js
--- a/src/locale/bg.js
+++ b/src/locale/bg.js
@@ -3,13 +3,29 @@ import dayjs from 'dayjs'
 
 const locale = {
   name: 'bg',
-  weekdays: 'Неделя_Понеделник_Вторник_Сряда_Четвъртък_Петък_Събота'.split('_'),
+  weekdays: 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),
   weekdaysShort: 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
   weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
-  months: 'Януари_Февруари_Март_Април_Май_Юни_Юли_Август_Септември_Октомври_Ноември_Декември'.split('_'),
-  monthsShort: 'Янр_Фев_Мар_Апр_Май_Юни_Юли_Авг_Сеп_Окт_Ное_Дек'.split('_'),
+  months: 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
+  monthsShort: 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
   weekStart: 1,
-  ordinal: n => `${n}.`,
+  ordinal: (n) => {
+    const last2Digits = n % 100
+    if (last2Digits > 10 && last2Digits < 20) {
+      return `${n}-ти`
+    }
+
+    const lastDigit = n % 10
+    if (lastDigit === 1) {
+      return `${n}-ви`
+    } else if (lastDigit === 2) {
+      return `${n}-ри`
+    } else if (lastDigit === 7 || lastDigit === 8) {
+      return `${n}-ми`
+    }
+
+    return `${n}-ти`
+  },
   formats: {
     LT: 'H:mm',
     LTS: 'H:mm:ss',
@@ -27,7 +43,7 @@ const locale = {
     h: 'час',
     hh: '%d часа',
     d: 'ден',
-    dd: '%d дни',
+    dd: '%d дена',
     M: 'месец',
     MM: '%d месеца',
     y: 'година',
diff --git a/src/locale/sv-fi.js b/src/locale/sv-fi.js
new file mode 100644
--- /dev/null
+++ b/src/locale/sv-fi.js
@@ -0,0 +1,50 @@
+// Finland Swedish [sv-fi]
+import dayjs from 'dayjs'
+
+const locale = {
+  name: 'sv-fi',
+  weekdays: 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),
+  weekdaysShort: 'sön_mån_tis_ons_tor_fre_lör'.split('_'),
+  weekdaysMin: 'sö_må_ti_on_to_fr_lö'.split('_'),
+  months: 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),
+  monthsShort: 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
+  weekStart: 1,
+  yearStart: 4,
+  ordinal: (n) => {
+    const b = n % 10
+    const o = (b === 1) || (b === 2) ? 'a' : 'e'
+    return `[${n}${o}]`
+  },
+  formats: {
+    LT: 'HH.mm',
+    LTS: 'HH.mm.ss',
+    L: 'DD.MM.YYYY',
+    LL: 'D. MMMM YYYY',
+    LLL: 'D. MMMM YYYY, [kl.] HH.mm',
+    LLLL: 'dddd, D. MMMM YYYY, [kl.] HH.mm',
+    l: 'D.M.YYYY',
+    ll: 'D. MMM YYYY',
+    lll: 'D. MMM YYYY, [kl.] HH.mm',
+    llll: 'ddd, D. MMM YYYY, [kl.] HH.mm'
+  },
+  relativeTime: {
+    future: 'om %s',
+    past: 'för %s sedan',
+    s: 'några sekunder',
+    m: 'en minut',
+    mm: '%d minuter',
+    h: 'en timme',
+    hh: '%d timmar',
+    d: 'en dag',
+    dd: '%d dagar',
+    M: 'en månad',
+    MM: '%d månader',
+    y: 'ett år',
+    yy: '%d år'
+  }
+}
+
+dayjs.locale(locale, null, true)
+
+export default locale
+
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
@@ -13,6 +13,11 @@ const matchWord = /\d*[^\s\d-_:/()]+/ // Word
 
 let locale = {}
 
+let parseTwoDigitYear = function (input) {
+  input = +input
+  return input + (input > 68 ? 1900 : 2000)
+}
+
 function offsetFromString(string) {
   if (!string) return 0
   if (string === 'Z') return 0
@@ -111,8 +116,7 @@ const expressions = {
   }],
   Y: [matchSigned, addInput('year')],
   YY: [match2, function (input) {
-    input = +input
-    this.year = input + (input > 68 ? 1900 : 2000)
+    this.year = parseTwoDigitYear(input)
   }],
   YYYY: [match4, addInput('year')],
   Z: zoneExpressions,
@@ -171,6 +175,7 @@ function makeParser(format) {
 
 const parseFormattedInput = (input, format, utc) => {
   try {
+    if (['x', 'X'].indexOf(format) > -1) return new Date((format === 'X' ? 1000 : 1) * input)
     const parser = makeParser(format)
     const {
       year, month, day, hours, minutes, seconds, milliseconds, zone
@@ -201,6 +206,9 @@ const parseFormattedInput = (input, format, utc) => {
 
 export default (o, C, d) => {
   d.p.customParseFormat = true
+  if (o && o.parseTwoDigitYear) {
+    ({ parseTwoDigitYear } = o)
+  }
   const proto = C.prototype
   const oldParse = proto.parse
   proto.parse = function (cfg) {
diff --git a/src/plugin/dayOfYear/index.js b/src/plugin/dayOfYear/index.js
--- a/src/plugin/dayOfYear/index.js
+++ b/src/plugin/dayOfYear/index.js
@@ -1,7 +1,8 @@
-export default (o, c) => {
+export default (o, c, d) => {
   const proto = c.prototype
   proto.dayOfYear = function (input) {
-    const dayOfYear = Math.round((this.startOf('day') - this.startOf('year')) / 864e5) + 1
+    // d(this) is for badMutable
+    const dayOfYear = Math.round((d(this).startOf('day') - d(this).startOf('year')) / 864e5) + 1
     return input == null ? dayOfYear : this.add(input - dayOfYear, 'day')
   }
 }
diff --git a/types/index.d.ts b/types/index.d.ts
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -10,7 +10,7 @@ declare function dayjs (date?: dayjs.ConfigType, format?: dayjs.OptionType, loca
 
 declare namespace dayjs {
   interface ConfigTypeMap {
-    default: string | number | Date | Dayjs
+    default: string | number | Date | Dayjs | null | undefined
   }
 
   export type ConfigType = ConfigTypeMap[keyof ConfigTypeMap]
@@ -286,7 +286,9 @@ declare namespace dayjs {
      * const date1 = dayjs('2019-01-25')
      * const date2 = dayjs('2018-06-05')
      * date1.diff(date2) // 20214000000 default milliseconds
+     * date1.diff() // milliseconds to current time
      * ```
+     *
      * To get the difference in another unit of measurement, pass that measurement as the second argument.
      * ```
      * const date1 = dayjs('2019-01-25')
@@ -296,7 +298,7 @@ declare namespace dayjs {
      *
      * Docs: https://day.js.org/docs/en/display/difference
      */
-    diff(date: ConfigType, unit?: QUnitType | OpUnitType, float?: boolean): number
+    diff(date?: ConfigType, unit?: QUnitType | OpUnitType, float?: boolean): number
     /**
      * This returns the number of **milliseconds** since the Unix Epoch of the Day.js object.
      * ```
diff --git a/types/plugin/customParseFormat.d.ts b/types/plugin/customParseFormat.d.ts
--- a/types/plugin/customParseFormat.d.ts
+++ b/types/plugin/customParseFormat.d.ts
@@ -1,4 +1,8 @@
 import { PluginFunc } from 'dayjs'
 
-declare const plugin: PluginFunc
+declare interface PluginOptions {
+    parseTwoDigitYear?: (yearString: string) => number
+}
+
+declare const plugin: PluginFunc<PluginOptions>
 export = plugin
diff --git a/types/plugin/isBetween.d.ts b/types/plugin/isBetween.d.ts
--- a/types/plugin/isBetween.d.ts
+++ b/types/plugin/isBetween.d.ts
@@ -5,6 +5,6 @@ export = plugin
 
 declare module 'dayjs' {
   interface Dayjs {
-    isBetween(a: ConfigType, b: ConfigType, c?: OpUnitType | null, d?: string): boolean
+    isBetween(a: ConfigType, b: ConfigType, c?: OpUnitType | null, d?: '()' | '[]' | '[)' | '(]'): boolean
   }
 }
diff --git a/types/plugin/utc.d.ts b/types/plugin/utc.d.ts
--- a/types/plugin/utc.d.ts
+++ b/types/plugin/utc.d.ts
@@ -15,5 +15,5 @@ declare module 'dayjs' {
     utcOffset(offset: number, keepLocalTime?: boolean): Dayjs
   }
 
-  export function utc(config?: ConfigType, format?: string): Dayjs
+  export function utc(config?: ConfigType, format?: string, strict?: boolean): Dayjs
 }

diff --git a/test/locale/bg.test.js b/test/locale/bg.test.js
new file mode 100644
--- /dev/null
+++ b/test/locale/bg.test.js
@@ -0,0 +1,67 @@
+import moment from 'moment'
+import MockDate from 'mockdate'
+import dayjs from '../../src'
+import relativeTime from '../../src/plugin/relativeTime'
+import advancedFormat from '../../src/plugin/advancedFormat'
+import '../../src/locale/bg'
+
+dayjs.extend(relativeTime)
+dayjs.extend(advancedFormat)
+
+beforeEach(() => {
+  MockDate.set(new Date())
+})
+
+afterEach(() => {
+  MockDate.reset()
+})
+
+it('Format Month with locale function', () => {
+  for (let i = 0; i <= 7; i += 1) {
+    const dayjsBG = dayjs().locale('bg').add(i, 'day')
+    const momentBG = moment().locale('bg').add(i, 'day')
+    const testFormat1 = 'DD MMMM YYYY MMM'
+    const testFormat2 = 'MMMM'
+    const testFormat3 = 'MMM'
+    expect(dayjsBG.format(testFormat1)).toEqual(momentBG.format(testFormat1))
+    expect(dayjsBG.format(testFormat2)).toEqual(momentBG.format(testFormat2))
+    expect(dayjsBG.format(testFormat3)).toEqual(momentBG.format(testFormat3))
+  }
+})
+
+it('RelativeTime: Time from X', () => {
+  const T = [
+    [44.4, 'second'], // a few seconds
+    [89.5, 'second'], // a minute
+    [130, 'second'], // two minutes
+    [43, 'minute'], // 44 minutes
+    [1, 'hour'], // 1 hour
+    [21, 'hour'], // 21 hours
+    [2, 'day'], // 2 days
+    [25, 'day'], // 25 days
+    [2, 'month'], // 2 months
+    [10, 'month'], // 10 months
+    [18, 'month'], // 2 years
+    [15, 'year'] // 15 years
+  ]
+
+  T.forEach((t) => {
+    dayjs.locale('bg')
+    moment.locale('bg')
+    expect(dayjs().from(dayjs().add(t[0], t[1])))
+      .toBe(moment().from(moment().add(t[0], t[1])))
+    expect(dayjs().from(dayjs().add(t[0], t[1]), true))
+      .toBe(moment().from(moment().add(t[0], t[1]), true))
+  })
+})
+
+it('Ordinal', () => {
+  dayjs.locale('bg')
+  moment.locale('bg')
+
+  for (let d = 1; d <= 31; d += 1) {
+    const day = d < 10 ? `0${d}` : d
+    const date = `2021-01-${day}`
+    expect(dayjs(date).format('Do')).toBe(moment(date).format('Do'))
+  }
+})
diff --git a/test/locale/sv-fi.test.js b/test/locale/sv-fi.test.js
new file mode 100644
--- /dev/null
+++ b/test/locale/sv-fi.test.js
@@ -0,0 +1,35 @@
+import dayjs from '../../src'
+import localizedFormat from '../../src/plugin/localizedFormat'
+import '../../src/locale/sv-fi'
+
+dayjs.extend(localizedFormat)
+
+it('Finland Swedish locale', () => {
+  // time
+  expect(dayjs('2019-02-01 12:34:56').locale('sv-fi').format('LT'))
+    .toBe('12.34')
+  expect(dayjs('2019-02-01 23:45:56').locale('sv-fi').format('LTS'))
+    .toBe('23.45.56')
+
+  // date
+  expect(dayjs('2019-02-01').locale('sv-fi').format('L'))
+    .toBe('01.02.2019')
+  expect(dayjs('2019-12-15').locale('sv-fi').format('LL'))
+    .toBe('15. december 2019')
+  // short
+  expect(dayjs('2019-02-01').locale('sv-fi').format('l'))
+    .toBe('1.2.2019')
+  expect(dayjs('2019-12-15').locale('sv-fi').format('ll'))
+    .toBe('15. dec 2019')
+
+  // date and time
+  expect(dayjs('2019-03-01 12:30').locale('sv-fi').format('LLL'))
+    .toBe('1. mars 2019, kl. 12.30')
+  expect(dayjs('2021-06-12 17:30').locale('sv-fi').format('LLLL'))
+    .toBe('lördag, 12. juni 2021, kl. 17.30')
+  // short
+  expect(dayjs('2019-03-01 12:30').locale('sv-fi').format('lll'))
+    .toBe('1. mar 2019, kl. 12.30')
+  expect(dayjs('2021-06-01 17:30').locale('sv-fi').format('llll'))
+    .toBe('tis, 1. jun 2021, kl. 17.30')
+})
diff --git a/test/parse.test.js b/test/parse.test.js
--- a/test/parse.test.js
+++ b/test/parse.test.js
@@ -89,11 +89,14 @@ describe('Parse', () => {
     expect(ds.millisecond()).toEqual(ms.millisecond())
   })
 
-  it('String Other, Null and isValid', () => {
+  it('String Other, Undefined and Null and isValid', () => {
     global.console.warn = jest.genMockFunction()// moment.js otherString will throw warn
     expect(dayjs('otherString').toString().toLowerCase()).toBe(moment('otherString').toString().toLowerCase())
+    expect(dayjs(undefined).toDate()).toEqual(moment(undefined).toDate())
     expect(dayjs().isValid()).toBe(true)
+    expect(dayjs(undefined).isValid()).toBe(true)
     expect(dayjs('').isValid()).toBe(false)
+    expect(dayjs(null).isValid()).toBe(false)
     expect(dayjs('otherString').isValid()).toBe(false)
     expect(dayjs(null).toString().toLowerCase()).toBe(moment(null).toString().toLowerCase())
   })
@@ -201,4 +204,12 @@ describe('REGEX_PARSE', () => {
     expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
     expect(d).toBe(null)
   })
+
+  // dots should not be matched, and fallback to Date
+  it('2021.01.03', () => {
+    const date = '2021.01.03'
+    const d = date.match(REGEX_PARSE)
+    expect(dayjs(date).valueOf()).toBe(moment(date).valueOf())
+    expect(d).toBe(null)
+  })
 })
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,10 +2,12 @@ import MockDate from 'mockdate'
 import moment from 'moment'
 import dayjs from '../../src'
 import badMutable from '../../src/plugin/badMutable'
+import dayOfYear from '../../src/plugin/dayOfYear'
 import weekOfYear from '../../src/plugin/weekOfYear'
 import '../../src/locale/zh-cn'
 
 dayjs.extend(badMutable)
+dayjs.extend(dayOfYear)
 dayjs.extend(weekOfYear)
 
 beforeEach(() => {
@@ -188,7 +190,14 @@ it('isAfter isBefore isSame', () => {
   expect(d.isAfter()).toBe(false)
 })
 
-it('WeekOfYear get week won"t change instance', () => {
+it('DayOfYear get day won\'t change instance', () => {
+  const d = dayjs()
+  const format = d.format()
+  d.dayOfYear()
+  expect(d.format()).toBe(format)
+})
+
+it('WeekOfYear get week won\'t change instance', () => {
   const d = dayjs()
   const format = d.format()
   d.week()
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
@@ -355,3 +355,25 @@ it('parse a string for MMM month format with underscore delimiter', () => {
   expect(dayjs(input2, format2).valueOf()).toBe(moment(input2, format2).valueOf())
 })
 
+it('custom two-digit year parse function', () => {
+  delete customParseFormat.$i // this allow plugin to be installed again
+  dayjs.extend(customParseFormat, {
+    parseTwoDigitYear: yearString => (+yearString) + 1800
+  })
+  const format = 'YY-MM-DD'
+  const input = '00-05-02'
+  expect(dayjs(input, format).year()).toBe(1800)
+  const input2 = '50-05-02'
+  expect(dayjs(input2, format).year()).toBe(1850)
+  const input3 = '99-05-02'
+  expect(dayjs(input3, format).year()).toBe(1899)
+})
+
+it('parse X x', () => {
+  const input = '1410715640.579'
+  const format = 'X'
+  expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
+  const input2 = '1410715640579'
+  const format2 = 'x'
+  expect(dayjs(input2, format2).valueOf()).toBe(moment(input2, format2).valueOf())
+})
diff --git a/test/plugin/updateLocale.test.js b/test/plugin/updateLocale.test.js
--- a/test/plugin/updateLocale.test.js
+++ b/test/plugin/updateLocale.test.js
@@ -68,4 +68,15 @@ describe('Update locale', () => {
     expect(dayjs().format(formatString))
       .toEqual(moment().format(formatString))
   })
+
+  it('Update invalid date string', () => {
+    const locale = 'en'
+    const localeSetting = { invalidDate: 'bad date' }
+    dayjs.updateLocale(locale, localeSetting)
+    moment.updateLocale(locale, localeSetting)
+    dayjs.locale(locale)
+    moment.locale(locale)
+    expect(dayjs('').format()).toBe(moment('').format())
+    expect(dayjs('otherString').format()).toBe(moment('otherString').format())
+  })
 })

Implement ordinal in Bulgarian translation
Currently, the ordinal is missing from Bulgarian translation, or more correctly, it is implemented in a wrong way.

Current: `25.`

Expected: `25-ти`

test/timezone.test.js(1) test/timezone.test.js(2) test/timezone.test.js(3) test/timezone.test.js(4)
test/parse.test.js test/locale/sv-fi.test.js test/plugin/updateLocale.test.js test/locale/bg.test.js test/plugin/badMutable.test.js test/plugin/customParseFormat.test.js