diff --git a/src/index.js b/src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -401,5 +401,5 @@ dayjs.unix = timestamp => (
 
 dayjs.en = Ls[L]
 dayjs.Ls = Ls
-
+dayjs.p = {}
 export default dayjs
diff --git a/src/locale/en-nz.js b/src/locale/en-nz.js
--- a/src/locale/en-nz.js
+++ b/src/locale/en-nz.js
@@ -9,7 +9,11 @@ const locale = {
   weekdaysShort: 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
   monthsShort: 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
   weekdaysMin: 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
-  ordinal: n => n,
+  ordinal: (n) => {
+    const s = ['th', 'st', 'nd', 'rd']
+    const v = n % 100
+    return `[${n}${s[(v - 20) % 10] || s[v] || s[0]}]`
+  },
   formats: {
     LT: 'h:mm A',
     LTS: 'h:mm:ss A',
diff --git a/src/locale/hu.js b/src/locale/hu.js
--- a/src/locale/hu.js
+++ b/src/locale/hu.js
@@ -13,17 +13,17 @@ const locale = {
   relativeTime: {
     future: '%s múlva',
     past: '%s',
-    s: 'néhány másodperc',
-    m: 'egy perc',
-    mm: '%d perc',
-    h: 'egy óra',
-    hh: '%d óra',
-    d: 'egy nap',
-    dd: '%d nap',
-    M: 'egy hónap',
-    MM: '%d hónap',
-    y: 'egy éve',
-    yy: '%d év'
+    s: (_, s, ___, isFuture) => `néhány másodperc${isFuture || s ? '' : 'e'}`,
+    m: (_, s, ___, isFuture) => `egy perc${isFuture || s ? '' : 'e'}`,
+    mm: (n, s, ___, isFuture) => `${n} perc${isFuture || s ? '' : 'e'}`,
+    h: (_, s, ___, isFuture) => `egy ${isFuture || s ? 'óra' : 'órája'}`,
+    hh: (n, s, ___, isFuture) => `${n} ${isFuture || s ? 'óra' : 'órája'}`,
+    d: (_, s, ___, isFuture) => `egy ${isFuture || s ? 'nap' : 'napja'}`,
+    dd: (n, s, ___, isFuture) => `${n} ${isFuture || s ? 'nap' : 'napja'}`,
+    M: (_, s, ___, isFuture) => `egy ${isFuture || s ? 'hónap' : 'hónapja'}`,
+    MM: (n, s, ___, isFuture) => `${n} ${isFuture || s ? 'hónap' : 'hónapja'}`,
+    y: (_, s, ___, isFuture) => `egy ${isFuture || s ? 'év' : 'éve'}`,
+    yy: (n, s, ___, isFuture) => `${n} ${isFuture || s ? 'év' : 'éve'}`
   },
   formats: {
     LT: 'H:mm',
@@ -38,4 +38,3 @@ const locale = {
 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
@@ -182,6 +182,7 @@ const parseFormattedInput = (input, format, utc) => {
 
 
 export default (o, C, d) => {
+  d.p.customParseFormat = true
   const proto = C.prototype
   const oldParse = proto.parse
   proto.parse = function (cfg) {
diff --git a/src/plugin/devHelper/index.js b/src/plugin/devHelper/index.js
new file mode 100644
--- /dev/null
+++ b/src/plugin/devHelper/index.js
@@ -0,0 +1,18 @@
+/* eslint-disable no-console */
+export default (o, c, d) => {
+  if (process.env.NODE_ENV !== 'production') {
+    const proto = c.prototype
+    const oldParse = proto.parse
+    proto.parse = function (cfg) {
+      const { date } = cfg
+      if (typeof date === 'string' && date.length === 13) {
+        console.warn(`To parse a Unix timestamp like ${date}, you should pass it as a Number. https://day.js.org/docs/en/parse/unix-timestamp-milliseconds`)
+      }
+      if (cfg.args.length >= 2 && !d.p.customParseFormat) {
+        console.warn(`To parse a date-time string like ${date} using the given format, you should enable customParseFormat plugin first. https://day.js.org/docs/en/parse/string-format`)
+      }
+      return oldParse.bind(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
@@ -179,11 +179,13 @@ export default (option, Dayjs, dayjs) => {
   dayjs.isDuration = isDuration
 
   const oldAdd = Dayjs.prototype.add
-  Dayjs.prototype.add = function (addition, units) {
-    if (isDuration(addition)) {
-      addition = addition.asMilliseconds()
-      units = 'ms'
-    }
-    return oldAdd.bind(this)(addition, units)
+  const oldSubtract = Dayjs.prototype.subtract
+  Dayjs.prototype.add = function (value, unit) {
+    if (isDuration(value)) value = value.asMilliseconds()
+    return oldAdd.bind(this)(value, unit)
+  }
+  Dayjs.prototype.subtract = function (value, unit) {
+    if (isDuration(value)) value = value.asMilliseconds()
+    return oldSubtract.bind(this)(value, unit)
   }
 }
diff --git a/src/plugin/minMax/index.js b/src/plugin/minMax/index.js
--- a/src/plugin/minMax/index.js
+++ b/src/plugin/minMax/index.js
@@ -1,7 +1,7 @@
 export default (o, c, d) => {
   const sortBy = (method, dates) => {
-    if (!dates.length) {
-      return d()
+    if (!dates || !dates.length || !dates[0] || (dates.length === 1 && !dates[0].length)) {
+      return null
     }
     if (dates.length === 1 && dates[0].length > 0) {
       [dates] = dates
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
@@ -1,3 +1,5 @@
+import { MIN, MS } from '../../constant'
+
 const typeToPos = {
   year: 0,
   month: 1,
@@ -7,8 +9,6 @@ const typeToPos = {
   second: 5
 }
 
-const ms = 'ms'
-
 // Cache time-zone lookups from Intl.DateTimeFormat,
 // as it is a *very* slow method.
 const dtfCache = {}
@@ -94,10 +94,15 @@ export default (o, c, d) => {
 
   const proto = c.prototype
 
-  proto.tz = function (timezone = defaultTimezone) {
+  proto.tz = function (timezone = defaultTimezone, keepLocalTime) {
+    const oldOffset = this.utcOffset()
     const target = this.toDate().toLocaleString('en-US', { timeZone: timezone })
     const diff = Math.round((this.toDate() - new Date(target)) / 1000 / 60)
-    const ins = d(target).$set(ms, this.$ms).utcOffset(localUtcOffset - diff, true)
+    let ins = d(target).$set(MS, this.$ms).utcOffset(localUtcOffset - diff, true)
+    if (keepLocalTime) {
+      const newOffset = ins.utcOffset()
+      ins = ins.add(oldOffset - newOffset, MIN)
+    }
     ins.$x.$timezone = timezone
     return ins
   }
@@ -109,14 +114,16 @@ export default (o, c, d) => {
     return result && result.value
   }
 
-  d.tz = function (input, timezone = defaultTimezone) {
+  d.tz = function (input, arg1, arg2) {
+    const parseFormat = arg2 && arg1
+    const timezone = arg2 || arg1 || defaultTimezone
     const previousOffset = tzOffset(+d(), timezone)
     let localTs
     if (typeof input !== 'string') {
       // timestamp number || js Date || Day.js
       localTs = d(input) + (previousOffset * 60 * 1000)
     }
-    localTs = localTs || d.utc(input).valueOf()
+    localTs = localTs || d.utc(input, parseFormat).valueOf()
     const [targetTs, targetOffset] = fixOffset(localTs, previousOffset, timezone)
     const ins = d(targetTs).utcOffset(targetOffset)
     ins.$x.$timezone = timezone
diff --git a/types/index.d.ts b/types/index.d.ts
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -21,79 +21,380 @@ declare namespace dayjs {
 
   class Dayjs {
     constructor (config?: ConfigType)
-
+    /**
+     * All Day.js objects are immutable. Still, `dayjs#clone` can create a clone of the current object if you need one.
+     * ```
+     * dayjs().clone()// => Dayjs
+     * dayjs(dayjs('2019-01-25')) // passing a Dayjs object to a constructor will also clone it
+     * ```
+     * Docs: https://day.js.org/docs/en/parse/dayjs-clone
+     */
     clone(): Dayjs
-
+    /**
+     * This returns a `boolean` indicating whether the Day.js object contains a valid date or not.
+     * ```
+     * dayjs().isValid()// => boolean
+     * ```
+     * Docs: https://day.js.org/docs/en/parse/is-valid
+     */
     isValid(): boolean
-
+    /**
+     * Get the year.
+     * ```
+     * dayjs().year()// => 2020
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/year
+     */
     year(): number
-
+    /**
+     * Set the year.
+     * ```
+     * dayjs().year(2000)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/year
+     */
     year(value: number): Dayjs
-
+    /**
+     * Get the month.
+     *
+     * Months are zero indexed, so January is month 0.
+     * ```
+     * dayjs().month()// => 0-11
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/month
+     */
     month(): number
-
+    /**
+     * Set the month.
+     *
+     * Months are zero indexed, so January is month 0.
+     *
+     * Accepts numbers from 0 to 11. If the range is exceeded, it will bubble up to the year.
+     * ```
+     * dayjs().month(0)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/month
+     */
     month(value: number): Dayjs
-
+    /**
+     * Get the date of the month.
+     * ```
+     * dayjs().date()// => 1-31
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/date
+     */
     date(): number
-
+    /**
+     * Set the date of the month.
+     *
+     * Accepts numbers from 1 to 31. If the range is exceeded, it will bubble up to the months.
+     * ```
+     * dayjs().date(1)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/date
+     */
     date(value: number): Dayjs
-
+    /**
+     * Get the day of the week.
+     *
+     * Returns numbers from 0 (Sunday) to 6 (Saturday).
+     * ```
+     * dayjs().day()// 0-6
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/day
+     */
     day(): number
-
+    /**
+     * Set the day of the week.
+     *
+     * Accepts numbers from 0 (Sunday) to 6 (Saturday). If the range is exceeded, it will bubble up to other weeks.
+     * ```
+     * dayjs().day(0)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/day
+     */
     day(value: number): Dayjs
-
+    /**
+     * Get the hour.
+     * ```
+     * dayjs().hour()// => 0-23
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/hour
+     */
     hour(): number
-
+    /**
+     * Set the hour.
+     *
+     * Accepts numbers from 0 to 23. If the range is exceeded, it will bubble up to the day.
+     * ```
+     * dayjs().hour(12)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/hour
+     */
     hour(value: number): Dayjs
-
+    /**
+     * Get the minutes.
+     * ```
+     * dayjs().minute()// => 0-59
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/minute
+     */
     minute(): number
-
+    /**
+     * Set the minutes.
+     *
+     * Accepts numbers from 0 to 59. If the range is exceeded, it will bubble up to the hour.
+     * ```
+     * dayjs().minute(59)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/minute
+     */
     minute(value: number): Dayjs
-
+    /**
+     * Get the seconds.
+     * ```
+     * dayjs().second()// => 0-59
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/second
+     */
     second(): number
-
+    /**
+     * Set the seconds.
+     *
+     * Accepts numbers from 0 to 59. If the range is exceeded, it will bubble up to the minutes.
+     * ```
+     * dayjs().second(1)// Dayjs
+     * ```
+     */
     second(value: number): Dayjs
-
+    /**
+     * Get the milliseconds.
+     * ```
+     * dayjs().millisecond()// => 0-999
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/millisecond
+     */
     millisecond(): number
-
+    /**
+     * Set the milliseconds.
+     *
+     * Accepts numbers from 0 to 999. If the range is exceeded, it will bubble up to the seconds.
+     * ```
+     * dayjs().millisecond(1)// => Dayjs
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/millisecond
+     */
     millisecond(value: number): Dayjs
-
+    /**
+     * Generic setter, accepting unit as first argument, and value as second, returns a new instance with the applied changes.
+     *
+     * In general:
+     * ```
+     * dayjs().set(unit, value) === dayjs()[unit](value)
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     * ```
+     * dayjs().set('date', 1)
+     * dayjs().set('month', 3) // April
+     * dayjs().set('second', 30)
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/set
+     */
     set(unit: UnitType, value: number): Dayjs
-
+    /**
+     * String getter, returns the corresponding information getting from Day.js object.
+     *
+     * In general:
+     * ```
+     * dayjs().get(unit) === dayjs()[unit]()
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     * ```
+     * dayjs().get('year')
+     * dayjs().get('month') // start 0
+     * dayjs().get('date')
+     * ```
+     * Docs: https://day.js.org/docs/en/get-set/get
+     */
     get(unit: UnitType): number
-
-    add(value: number, unit: OpUnitType): Dayjs
-
-    subtract(value: number, unit: OpUnitType): Dayjs
-
+    /**
+     * Returns a cloned Day.js object with a specified amount of time added.
+     * ```
+     * dayjs().add(7, 'day')// => Dayjs
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/manipulate/add
+     */
+    add(value: number, unit?: OpUnitType): Dayjs
+    /**
+     * Returns a cloned Day.js object with a specified amount of time subtracted.
+     * ```
+     * dayjs().subtract(7, 'year')// => Dayjs
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/manipulate/subtract
+     */
+    subtract(value: number, unit?: OpUnitType): Dayjs
+    /**
+     * Returns a cloned Day.js object and set it to the start of a unit of time.
+     * ```
+     * dayjs().startOf('year')// => Dayjs
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/manipulate/start-of
+     */
     startOf(unit: OpUnitType): Dayjs
-
+    /**
+     * Returns a cloned Day.js object and set it to the end of a unit of time.
+     * ```
+     * dayjs().endOf('month')// => Dayjs
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/manipulate/end-of
+     */
     endOf(unit: OpUnitType): Dayjs
-
+    /**
+     * Get the formatted date according to the string of tokens passed in.
+     *
+     * To escape characters, wrap them in square brackets (e.g. [MM]).
+     * ```
+     * dayjs().format()// => current date in ISO8601, without fraction seconds e.g. '2020-04-02T08:02:17-05:00'
+     * dayjs('2019-01-25').format('[YYYYescape] YYYY-MM-DDTHH:mm:ssZ[Z]')// 'YYYYescape 2019-01-25T00:00:00-02:00Z'
+     * dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'
+     * ```
+     * Docs: https://day.js.org/docs/en/display/format
+     */
     format(template?: string): string
-
+    /**
+     * This indicates the difference between two date-time in the specified unit.
+     *
+     * To get the difference in milliseconds, use `dayjs#diff`
+     * ```
+     * const date1 = dayjs('2019-01-25')
+     * const date2 = dayjs('2018-06-05')
+     * date1.diff(date2) // 20214000000 default milliseconds
+     * ```
+     * To get the difference in another unit of measurement, pass that measurement as the second argument.
+     * ```
+     * const date1 = dayjs('2019-01-25')
+     * date1.diff('2018-06-05', 'month') // 7
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/display/difference
+     */
     diff(date: ConfigType, unit?: QUnitType | OpUnitType, float?: boolean): number
-
+    /**
+     * This returns the number of **milliseconds** since the Unix Epoch of the Day.js object.
+     * ```
+     * dayjs('2019-01-25').valueOf() // 1548381600000
+     * +dayjs(1548381600000) // 1548381600000
+     * ```
+     * To get a Unix timestamp (the number of seconds since the epoch) from a Day.js object, you should use Unix Timestamp `dayjs#unix()`.
+     *
+     * Docs: https://day.js.org/docs/en/display/unix-timestamp-milliseconds
+     */
     valueOf(): number
-
+    /**
+     * This returns the Unix timestamp (the number of **seconds** since the Unix Epoch) of the Day.js object.
+     * ```
+     * dayjs('2019-01-25').unix() // 1548381600
+     * ```
+     * This value is floored to the nearest second, and does not include a milliseconds component.
+     *
+     * Docs: https://day.js.org/docs/en/display/unix-timestamp
+     */
     unix(): number
-
+    /**
+     * Get the number of days in the current month.
+     * ```
+     * dayjs('2019-01-25').daysInMonth() // 31
+     * ```
+     * Docs: https://day.js.org/docs/en/display/days-in-month
+     */
     daysInMonth(): number
-
+    /**
+     * To get a copy of the native `Date` object parsed from the Day.js object use `dayjs#toDate`.
+     * ```
+     * dayjs('2019-01-25').toDate()// => Date
+     * ```
+     */
     toDate(): Date
-
+    /**
+     * To serialize as an ISO 8601 string.
+     * ```
+     * dayjs('2019-01-25').toJSON() // '2019-01-25T02:00:00.000Z'
+     * ```
+     * Docs: https://day.js.org/docs/en/display/as-json
+     */
     toJSON(): string
-
+    /**
+     * To format as an ISO 8601 string.
+     * ```
+     * dayjs('2019-01-25').toISOString() // '2019-01-25T02:00:00.000Z'
+     * ```
+     * Docs: https://day.js.org/docs/en/display/as-iso-string
+     */
     toISOString(): string
-
+    /**
+     * Returns a string representation of the date.
+     * ```
+     * dayjs('2019-01-25').toString() // 'Fri, 25 Jan 2019 02:00:00 GMT'
+     * ```
+     * Docs: https://day.js.org/docs/en/display/as-string
+     */
     toString(): string
-
+    /**
+     * Get the UTC offset in minutes.
+     * ```
+     * dayjs().utcOffset()
+     * ```
+     * Docs: https://day.js.org/docs/en/manipulate/utc-offset
+     */
     utcOffset(): number
-
+    /**
+     * This indicates whether the Day.js object is before the other supplied date-time.
+     * ```
+     * dayjs().isBefore(dayjs('2011-01-01')) // default milliseconds
+     * ```
+     * If you want to limit the granularity to a unit other than milliseconds, pass it as the second parameter.
+     * ```
+     * dayjs().isBefore('2011-01-01', 'year')// => boolean
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/query/is-before
+     */
     isBefore(date: ConfigType, unit?: OpUnitType): boolean
-
+    /**
+     * This indicates whether the Day.js object is the same as the other supplied date-time.
+     * ```
+     * dayjs().isSame(dayjs('2011-01-01')) // default milliseconds
+     * ```
+     * If you want to limit the granularity to a unit other than milliseconds, pass it as the second parameter.
+     * ```
+     * dayjs().isSame('2011-01-01', 'year')// => boolean
+     * ```
+     * Docs: https://day.js.org/docs/en/query/is-same
+     */
     isSame(date: ConfigType, unit?: OpUnitType): boolean
-
+    /**
+     * This indicates whether the Day.js object is after the other supplied date-time.
+     * ```
+     * dayjs().isAfter(dayjs('2011-01-01')) // default milliseconds
+     * ```
+     * If you want to limit the granularity to a unit other than milliseconds, pass it as the second parameter.
+     * ```
+     * dayjs().isAfter('2011-01-01', 'year')// => boolean
+     * ```
+     * Units are case insensitive, and support plural and short forms.
+     *
+     * Docs: https://day.js.org/docs/en/query/is-after
+     */
     isAfter(date: ConfigType, unit?: OpUnitType): boolean
 
     locale(): string
diff --git a/types/plugin/devHelper.d.ts b/types/plugin/devHelper.d.ts
new file mode 100644
--- /dev/null
+++ b/types/plugin/devHelper.d.ts
@@ -0,0 +1,4 @@
+import { PluginFunc } from 'dayjs'
+
+declare const plugin: PluginFunc
+export = plugin
diff --git a/types/plugin/duration.d.ts b/types/plugin/duration.d.ts
--- a/types/plugin/duration.d.ts
+++ b/types/plugin/duration.d.ts
@@ -56,6 +56,11 @@ declare namespace plugin {
 }
 
 declare module 'dayjs' {
+  interface Dayjs {
+    add(value: plugin.Duration): Dayjs
+    subtract(value: plugin.Duration): Dayjs
+  }
+
   export function duration(input?: plugin.DurationInputType , unit?: string): plugin.Duration
   export function isDuration(d: any): d is plugin.Duration
 }
diff --git a/types/plugin/localeData.d.ts b/types/plugin/localeData.d.ts
--- a/types/plugin/localeData.d.ts
+++ b/types/plugin/localeData.d.ts
@@ -4,7 +4,37 @@ declare const plugin: PluginFunc
 export = plugin
 
 declare module 'dayjs' {
+  type WeekdayNames = [string, string, string, string, string, string, string];
+  type MonthNames = [string, string, string, string, string, string, string, string, string, string, string, string];
+
+  interface InstanceLocaleDataReturn {
+    firstDayOfWeek(): number;
+    weekdays(instance?: Dayjs): WeekdayNames;
+    weekdaysShort(instance?: Dayjs): WeekdayNames;
+    weekdaysMin(instance?: Dayjs): WeekdayNames;
+    months(instance?: Dayjs): MonthNames;
+    monthsShort(instance?: Dayjs): MonthNames;
+    longDateFormat(format: string): string;
+  }
+
+  interface GlobalLocaleDataReturn {
+    firstDayOfWeek(): number;
+    weekdays(): WeekdayNames;
+    weekdaysShort(): WeekdayNames;
+    weekdaysMin(): WeekdayNames;
+    months(): MonthNames;
+    monthsShort(): MonthNames;
+    longDateFormat(format: string): string;
+  }
+
   interface Dayjs {
-    localeData(): any
+    localeData(): InstanceLocaleDataReturn;
   }
+
+  export function weekdays(localOrder?: boolean): WeekdayNames;
+  export function weekdaysShort(localOrder?: boolean): WeekdayNames;
+  export function weekdaysMin(localOrder?: boolean): WeekdayNames;
+  export function monthsShort(): MonthNames;
+  export function months(): MonthNames;
+  export function localeData(): GlobalLocaleDataReturn;
 }
diff --git a/types/plugin/timezone.d.ts b/types/plugin/timezone.d.ts
--- a/types/plugin/timezone.d.ts
+++ b/types/plugin/timezone.d.ts
@@ -5,11 +5,12 @@ export = plugin
 
 declare module 'dayjs' {
   interface Dayjs {
-    tz(timezone?: string): Dayjs
+    tz(timezone?: string, keepLocalTime?: boolean): Dayjs
   }
 
   interface DayjsTimezone {
     (date: ConfigType, timezone?: string): Dayjs
+    (date: ConfigType, format: string, timezone?: string): Dayjs
     guess(): string
     setDefault(timezone?: string): void
   }

diff --git a/test/locale/hu.test.js b/test/locale/hu.test.js
new file mode 100644
--- /dev/null
+++ b/test/locale/hu.test.js
@@ -0,0 +1,45 @@
+import moment from 'moment'
+import dayjs from '../../src'
+import relativeTime from '../../src/plugin/relativeTime'
+import '../../src/locale/hu'
+
+dayjs.extend(relativeTime)
+
+it('RelativeTime: Time from X', () => {
+  const T = [
+    [44.4, 'second'], // a few seconds
+    [89.5, 'second'], // a minute
+    [2, 'minute'], // 2 minutes
+    [43, 'minute'], // 43 minutes
+    [45, 'minute'], // an hour
+    [3, 'hour'], // 3 hours
+    [21, 'hour'], // 21 hours
+    [1, 'day'], // a day
+    [3, 'day'], // 3 day
+    [25, 'day'], // 25 days
+    [1, 'month'], // a month
+    [2, 'month'], // 2 month
+    [10, 'month'], // 10 month
+    [1, 'year'], // a year
+    [2, 'year'], // 2 year
+    [5, 'year'], // 5 year
+    [18, 'month'] // 2 years
+  ]
+
+  T.forEach((t) => {
+    dayjs.locale('hu')
+    moment.locale('hu')
+
+    const dayjsDay = dayjs()
+    const momentDay = moment()
+
+    const dayjsCompare = dayjs().add(t[0], t[1])
+    const momentCompare = moment().add(t[0], t[1])
+
+    expect(dayjsDay.from(dayjsCompare)).toBe(momentDay.from(momentCompare))
+
+    expect(dayjsDay.to(dayjsCompare)).toBe(momentDay.to(momentCompare))
+
+    expect(dayjsDay.from(dayjsCompare, true)).toBe(momentDay.from(momentCompare, true))
+  })
+})
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
@@ -139,7 +139,7 @@ describe('Add', () => {
   expect(a.add({ days: 5 }).days()).toBe(6)
 })
 
-describe('Add duration', () => {
+test('Add duration', () => {
   const a = dayjs('2020-10-01')
   const days = dayjs.duration(2, 'days')
   expect(a.add(days).format('YYYY-MM-DD')).toBe('2020-10-03')
@@ -151,6 +151,11 @@ describe('Subtract', () => {
   expect(a.subtract(b).days()).toBe(1)
 })
 
+test('Subtract duration', () => {
+  const a = dayjs('2020-10-20')
+  const days = dayjs.duration(2, 'days')
+  expect(a.subtract(days).format('YYYY-MM-DD')).toBe('2020-10-18')
+})
 
 describe('Seconds', () => {
   expect(dayjs.duration(500).seconds()).toBe(0)
diff --git a/test/plugin/minMax.test.js b/test/plugin/minMax.test.js
--- a/test/plugin/minMax.test.js
+++ b/test/plugin/minMax.test.js
@@ -18,10 +18,21 @@ const arg3 = dayjs('2017-01-01')
 const arg4 = dayjs('Invalid Date')
 
 it('Return current time if no argument', () => {
-  expect(dayjs.max().format())
-    .toBe(dayjs().format())
-  expect(dayjs.min().format())
-    .toBe(dayjs().format())
+  expect(dayjs.max())
+    .toBe(null)
+  expect(dayjs.min())
+    .toBe(null)
+  expect(dayjs.max(null))
+    .toBe(null)
+  expect(dayjs.min(null))
+    .toBe(null)
+})
+
+it('Return current time if passing empty array', () => {
+  expect(dayjs.max([]))
+    .toBe(null)
+  expect(dayjs.min([]))
+    .toBe(null)
 })
 
 it('Compare between arguments', () => {
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
@@ -1,11 +1,13 @@
 import MockDate from 'mockdate'
 import moment from 'moment-timezone'
 import dayjs from '../../src'
-import utc from '../../src/plugin/utc'
 import timezone from '../../src/plugin/timezone'
+import customParseFormat from '../../src/plugin/customParseFormat'
+import utc from '../../src/plugin/utc'
 
 dayjs.extend(utc)
 dayjs.extend(timezone)
+dayjs.extend(customParseFormat)
 
 beforeEach(() => {
   MockDate.set(new Date())
@@ -17,6 +19,7 @@ afterEach(() => {
 
 const NY = 'America/New_York'
 const VAN = 'America/Vancouver'
+const DEN = 'America/Denver'
 const TOKYO = 'Asia/Tokyo'
 
 describe('Guess', () => {
@@ -260,6 +263,14 @@ describe('set Default', () => {
   })
 })
 
+describe('keepLocalTime', () => {
+  const base = dayjs.tz('2013-11-18 11:55', 'America/Toronto')
+  it('keepLocalTime', () => {
+    expect(base.tz('Europe/Berlin').format()).toBe('2013-11-18T17:55:00+01:00')
+    expect(base.tz('Europe/Berlin', true).format()).toBe('2013-11-18T11:55:00+01:00')
+  })
+})
+
 describe('Get offsetName', () => {
   const dtz = dayjs.tz('2012-03-11 01:59:59', NY)
   it('short', () => {
@@ -273,3 +284,13 @@ describe('Get offsetName', () => {
     expect(d).toBe('Eastern Standard Time')
   })
 })
+
+describe('CustomPraseFormat', () => {
+  const result = 1602786600
+  it('normal', () => {
+    expect(dayjs.tz('2020/10/15 12:30', DEN).unix()).toBe(result)
+  })
+  it('custom', () => {
+    expect(dayjs.tz('10/15/2020 12:30', 'MM/DD/YYYY HH:mm', DEN).unix()).toBe(result)
+  })
+})

the unix timestamp didnt not pick up the timezone change correctly
**Describe the bug**
How to get the correct time stamp with a time on a specific timezone ?
I want to check the unix timestamp for 10/15/2020 12:30 PM at Denver, but neither of the approaches (3 and 4) works.

1.
//Los Angeles (correct)
console.log("local notz:", dayjs("10/15/2020 12:30 PM").unix().toString());
// local notz:1602790200
2.
//Los Angeles (wrong)
console.log("local:", dayjs.tz("10/15/2020 12:30 PM").unix().toString()); 
// local: 1602815400 
3.
// Denver (wrong)
console.log(
  "denver:",
  dayjs.tz("10/15/2020 12:30 PM", "America/Denver").unix().toString()
); 
//denver: 1602811800 
4.
// Denver (wrong)
console.log(
  "denver sep:",
  dayjs("10/15/2020 12:30 PM").tz("America/Denver").unix().toString()
); 
//denver sep: 1602790200 

**Expected behavior**
A clear and concise description of what you expected to happen.

1.1602790200
2.1602790200
3.1602793800
4.1602793800


**Information**
 - Day.js Version [e.g. v1.9.3]
 - OS: [e.g. macOS 10.15.7]
 - Browser [e.g. chrome 86]
 - Time zone: [e.g. GMT-07:00 DST (Pacific Daylight Time)]


test/timezone.test.js(1) test/timezone.test.js(2) test/timezone.test.js(3) test/timezone.test.js(4)
test/plugin/minMax.test.js test/locale/hu.test.js test/plugin/duration.test.js test/plugin/timezone.test.js