Repository: iamkun/dayjs (JavaScript)

Issue:
Add Latin locale
For [romcal](https://github.com/romcal/romcal), I need to add Latin locale to `dayjs`. Therefore I have some questions regarding this.

---

1. As Latin weekday names are composed mostly of two words (like `feria secunda` for Monday), should I use a command as follows?

```js
weekdays: 'Dominica-feria secunda-feria tertia-feria quarta-feria quinta-feria sexta-Sabbato'.split('-'),
```

---

2. There’s a subissue: in Latin, there are [two different ways to name the weekdays](https://la.wikipedia.org/wiki/Hebdomas), and a third one (e.g. used in the Roman Catholic Church) which modifies one of the former two:

A. using `dies` (used in the Ancient Rome):
   - `dies Solis`;
   - `dies Lunae`;
   - `dies Martis`;
   - `dies Mercurii`;
   - `dies Iovis`;
   - `dies Veneris`;
   - `dies Saturni`;

B. using `ferias` (numbering days, starting with 1 for Sunday):
   - `feria prima`;
   - `feria secunda`;
   - `feria tertia`;
   - `feria quarta`;
   - `feria quinta`;
   - `feria sexta`;
   - `feria septima`;

C. variation of the `feria` names, used in the RC Church (uses `Dominica` for Sunday and `Sabbato` for Saturday):
   - `Dominica`;
   - `feria secunda`;
   - `feria tertia`;
   - `feria quarta`;
   - `feria quinta`;
   - `feria sexta`;
   - `Sabbato`.

Now, I need the C one only, but some other people _might_ like some other names. If I implement this, I’d like to be as thorough as possible, so my question is: should I create three separate regions (like `la-va` for Vatican, i.e. the 3rd type of weekday names)? Or how else should I fix this?

---

3. Weekday names: when the `feria` names are used, one may shorten it by using Roman numerals (e.g. `feria sexta` → `fera VI`). I presume I should use these in `weekdaysShort`, but I need a confirmation. Seldom, simply the Roman numerals are used (like `IV`), for which I could use `weekdaysMin`.

---

4. Another thing is that in Latin, they don’t use Arabic numeral, instead they _always_ use Roman numerals (for days of month, year, weekday numbers). I suggest to use Arabic numerals in time format (I don’t think that in Ancient Rome, they used time format at all and nowadays, I believe they use Arabic numerals for time instead). But how do I output Roman numerals? Does `dayjs` include such a converter? Should I create a custom function within `la.js`?

---

5. As I know that you compare the output of `dayjs` with the output of Moment in `dayjs` tests, is it required to create `la.js` locale in Moment first?


Hints:
1. it's perfectly ok to use normal Array [].
2. It's up to you cause you are a native speaker. One locale or three locales will both be fine.
3. It's ok.
4. I don't really understand. Can you detail it, please?
5. There's no need, just add our own in the first place.

We use ISO 639-2 country code.
Check lists short codes for language here. https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
2. Okay, then if I’ll go the route of having three locales, how does the locale inheritance work? I don’t want to define common locale parts in all three locales.

3. Okay.

4. Okay, I’ll do my best.

Arabic numerals = 1, 2, 3, … Roman numerals = I, II, III, IV, …

 Date example: XX Iunii MMXX = 20 June 2020

Time format would 24h in Arabic numerals, e.g. 13:24.

Now, my question is about the conversion from Arabic numerals to Roman numerals: is there a builtin converter or should I create a function within the locale? If I need to create a function and I create it in the main, `la.js` locale, will it be inherited (i.e. defined) in the ‘sublocales’ like `la-va.js`?

---

6. Country and lang codes. `la` is code for Latin according to [ISO 369-2](https://en.m.wikipedia.org/wiki/List_of_ISO_639-2_codes). However, I believe that country code system you use is [ISO 3166-1 alpha-2](https://en.m.wikipedia.org/wiki/ISO_3166-1_alpha-2), which assigns [VA](https://en.m.wikipedia.org/wiki/ISO_3166-1_alpha-2#VA) for Vatican / the Holy See.
2 the best way might just be simple copy-paste. 

Yes, you have to create a function to make the conversion in locale file.
I have created the `la.js` locale. I isn’t perfect, as currently the `relativeTime` format uses Nominative case only (and thus `ad %d anni` [in %d years] is grammatically incorrect, but `%d anni` [%d years] is correct). Is there a way to check within the locale what is the context of the queried value? I think there is none, but without that I can’t see a way to return the correct form of the words. I wish there would be a way (like extra argument added to `dayjs` when invoking, as this would be other languages too (and then I could fix moment/moment#5408 (read [this comment](https://github.com/moment/moment/issues/5408#issuecomment-628598304) to get the main issue).

---

Anyway, as there is no `la.js` in Moment, should I create a test that would check if the output matches a fixed string?

---

I wanted to test the locale locally, but with my limited knowledge I could not make it work. This is what I have done:

1. Run `npm install && npm run-script build`.
2. In the repo root, I created a file called `testLa.js` with the following content:

```js
const dayjs = require('./dayjs.min.js');
dayjs.locale('la')

var l = dayjs.locale()

console.log(l)
```

3. Run the script (`node testLa.js`) and I have expected the output to be `la`, but it was `en`.

Now, I have read the [docs](https://day.js.org/docs/en/i18n/loading-into-nodejs), but adding `require('dayjs/locale/la')` throwed the following error:

```bash
$ node testLa.js 
internal/modules/cjs/loader.js:960
  throw err;
  ^

Error: Cannot find module 'dayjs/locale/la'
Require stack:
- /home/ts/git/c10n/dayjs/testLa.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:957:15)
    at Function.Module._load (internal/modules/cjs/loader.js:840:27)
    at Module.require (internal/modules/cjs/loader.js:1019:19)
    at require (internal/modules/cjs/helpers.js:77:18)
    at Object.<anonymous> (/home/ts/git/c10n/dayjs/testLa.js:2:1)
    at Module._compile (internal/modules/cjs/loader.js:1133:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
    at Module.load (internal/modules/cjs/loader.js:977:32)
    at Function.Module._load (internal/modules/cjs/loader.js:877:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/home/ts/git/c10n/dayjs/testLa.js' ]
}
```

I understand that the module was not found, but even if I change the path to `src/locale/la`, it won’t find anything.

---

Anyway, I’ve just create a PR, but it definately needs to be reviewed.
Sorry, I was busy lately. Could you help me with running `dayjs` from terminal using directly the code in the `src/` folder? That way I could double-check if all tests pass more easily. Thanks for you help.
I would manually change 'dayjs/locale/la' to '../src/locale/la' 😢  
> I would manually change 'dayjs/locale/la' to '../src/locale/la' cry

Where would you do that?
> > I would manually change 'dayjs/locale/la' to '../src/locale/la' cry
> 
> Where would you do that?

to replace this `Error: Cannot find module 'dayjs/locale/la'`
I have tried out your suggestion, but it still does not work, see below. All my scripts are located in the repo root.

<details>
   <summary><code>node testLa2.js</code> (with <code>require</code>)</summary>

Script contents:

```js
const dayjs = require('./dayjs.min.js')
require('./src/locale/la')
dayjs.locale('la')

var l = dayjs.locale()

console.log(l)
```

Error output:

```js
$ node testLa2.js 
/home/ts/git/c10n/dayjs/src/locale/la.js:2
import dayjs from 'dayjs'
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1053:16)
    at Module._compile (internal/modules/cjs/loader.js:1101:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Module.require (internal/modules/cjs/loader.js:1025:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at Object.<anonymous> (/home/ts/git/c10n/dayjs/testLa2.js:2:1)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
```
</details>

<details>
   <summary><code>node testLa2.mjs</code> (with <code>require</code>)</summary>

Script contents:

```js
const dayjs = require('./dayjs.min.js')
require('./src/locale/la')
dayjs.locale('la')

var l = dayjs.locale()

console.log(l)
```

Error output:

```js
$ node testLa2.mjs 
(node:275906) ExperimentalWarning: The ESM module loader is experimental.
file:///home/ts/git/c10n/dayjs/testLa2.mjs:1
const dayjs = require('./dayjs.min.js')
              ^

ReferenceError: require is not defined
    at file:///home/ts/git/c10n/dayjs/testLa2.mjs:1:15
    at ModuleJob.run (internal/modules/esm/module_job.js:139:37)
    at async Loader.import (internal/modules/esm/loader.js:179:24)
```
</details>

<details>
   <summary><code>node testLa2.js</code> (with <code>import</code>)</summary>

Script contents:

```js
import dayjs from './dayjs.min.js'
import './src/locale/la'
dayjs.locale('la')

var l = dayjs.locale()

console.log(l)
```

Error output:

```js
$ node testLa2.js 
(node:278457) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
/home/ts/git/c10n/dayjs/testLa2.js:1
import dayjs from './dayjs.min.js'
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (internal/modules/cjs/loader.js:1053:16)
    at Module._compile (internal/modules/cjs/loader.js:1101:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
```
</details>

<details>
   <summary><code>node testLa2.mjs</code> (with <code>import</code>)</summary>

Script contents:

```js
import dayjs from './dayjs.min.js'
import './src/locale/la'
dayjs.locale('la')

var l = dayjs.locale()

console.log(l)
```

Error output:

```js
$ node testLa2.mjs 
(node:279861) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/run_main.js:54
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/ts/git/c10n/dayjs/src/locale/la' imported from /home/ts/git/c10n/dayjs/testLa2.mjs
Did you mean to import ../src/locale/la.js?
    at finalizeResolution (internal/modules/esm/resolve.js:259:11)
    at moduleResolve (internal/modules/esm/resolve.js:636:10)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:726:11)
    at Loader.resolve (internal/modules/esm/loader.js:97:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:243:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:47:40)
    at link (internal/modules/esm/module_job.js:46:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}
```
</details>
please use `npm test` to test the source code 
Indeed, you’re right, there are failing tests, but I did not change anything in those files.

<details>
   <summary>Failing tests</summary>

```bash
Summary of all failing tests
 FAIL  test/parse.test.js
  ● Parse › moment-js like formatted dates

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2018-01-01T00:00:00+01:00"
    Received:
      "2018-01-01T01:00:00+01:00"

      37 |     expect(dayjs(d).valueOf()).toBe(moment(d).valueOf()) // not recommend
      38 |     d = '2018'
    > 39 |     expect(dayjs(d).format()).toBe(moment(d).format()) // not recommend
      40 |     d = '2018-05-02T11:12:13Z' // should go direct to new Date() rather our regex
      41 |     expect(dayjs(d).format()).toBe(moment(d).format()) // not recommend
      42 |   })
      
      at Object.<anonymous> (test/parse.test.js:39:31)

 FAIL  test/plugin/utc-utcOffset.test.js
  ● change hours when changing the utc offset in UTC mode

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      5
    Received:
      4

      70 |   expect(d.hour()).toBe(6)
      71 |   expect(d.utcOffset(0).hour()).toBe(6)
    > 72 |   expect(d.utcOffset(-60).hour()).toBe(5)
      73 |   expect(d.utcOffset(60).hour()).toBe(7)
      74 |   expect(d.utcOffset(-30).format('HH:mm')).toBe('06:01')
      75 |   expect(d.utcOffset(30).format('HH:mm')).toBe('07:01')
      
      at Object.<anonymous> (test/plugin/utc-utcOffset.test.js:72:35)

  ● keep hours when adding month in offset mode

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      6
    Received:
      5

      94 |   const dm8 = dayjs('2000-01-30T06:31:00-08:00').utcOffset(-8)
      95 | 
    > 96 |   expect(d10.add(1, 'month').hour()).toBe(6)
      97 |   expect(dm8.add(1, 'month').hour()).toBe(6)
      98 | 
      99 |   expect(d10.add(-2, 'month').hour()).toBe(6)
      
      at Object.<anonymous> (test/plugin/utc-utcOffset.test.js:96:38)

 FAIL  test/plugin/calendar.test.js
  ● No argument && null && undefined

    TypeError: Cannot convert undefined or null to object
        at hasOwnProperty (<anonymous>)

      17 | it('No argument && null && undefined', () => {
      18 |   expect(dayjs().calendar()).toEqual(moment().calendar())
    > 19 |   expect(dayjs().calendar(null)).toEqual(moment().calendar(null))
      20 |   expect(dayjs().calendar(undefined)).toEqual(moment().calendar(undefined))
      21 | })
      22 | 
      
      at hasOwnProp (node_modules/moment/moment.js:42:48)
      at isMomentInputObject (node_modules/moment/moment.js:3669:44)
      at isMomentInput (node_modules/moment/moment.js:3629:13)
      at Moment.calendar (node_modules/moment/moment.js:3729:17)
      at Object.<anonymous> (test/plugin/calendar.test.js:19:51)


Test Suites: 3 failed, 52 passed, 55 total
Tests:       4 failed, 505 passed, 509 total
Snapshots:   0 total
Time:        27.64s
Ran all test suites.
npm ERR! Test failed.  See above for more details.
```
</details>
All of our tests should be passed. You can submit a pull request with any change and test with our CI to see if there is an environmental issue.
 I’ve no idea how to fix those errors, but somehow it uses GMT+1 timezone instead of UTC.

Note that I use CET (winter timezone; GMT+1) and CEST (summer timezone; GMT+2) locally; although it should not be connected, it might be.
I'll try CET to see if I can reproduce this later.
@iamkun, I have just cloned your repo (`dev` branch, cf8b6a0) and run `npm install && npm test`. The dependencies seemed to be installed successfully (some warnings about deprecated modules/versions were output though), but the tests fail (2 test suites / 10 tests). See the outputs below.

<details>
   <summary><code>npm install</code></summary>

```bash
$ npm install
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
npm WARN deprecated circular-json@0.5.9: CircularJSON is in maintenance only, flatted is its successor.
npm WARN deprecated nodemailer@2.7.2: All versions below 4.0.1 of Nodemailer are deprecated. See https://nodemailer.com/status/
npm WARN deprecated request@2.88.0: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features!
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated request@2.75.0: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated mailcomposer@4.0.1: This project is unmaintained
npm WARN deprecated uws@9.14.0: New code is available at github.com/uNetworking/uWebSockets.js
npm WARN deprecated socks@1.1.9: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0
npm WARN deprecated circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor.
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated left-pad@1.3.0: use String.prototype.padStart()
npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
npm WARN deprecated hawk@3.1.3: This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
npm WARN deprecated node-uuid@1.4.8: Use uuid module instead
npm WARN deprecated buildmail@4.0.1: This project is unmaintained
npm WARN deprecated hoek@2.16.3: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated boom@2.10.1: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated cryptiles@2.0.5: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated sntp@1.0.9: This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.

> uws@9.14.0 install /home/ts/git/c10n/dayjs/node_modules/uws
> node-gyp rebuild > build_log.txt 2>&1 || exit 0


> wd@1.13.0 install /home/ts/git/c10n/dayjs/node_modules/wd
> node scripts/build-browser-scripts


> pre-commit@1.2.2 install /home/ts/git/c10n/dayjs/node_modules/pre-commit
> node install.js


> core-js@2.6.11 postinstall /home/ts/git/c10n/dayjs/node_modules/babel-register/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> core-js@2.6.11 postinstall /home/ts/git/c10n/dayjs/node_modules/babel-runtime/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"


> core-js@3.6.5 postinstall /home/ts/git/c10n/dayjs/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"


> ejs@2.7.4 postinstall /home/ts/git/c10n/dayjs/node_modules/ejs
> node ./postinstall.js

Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)


> core-js@2.6.11 postinstall /home/ts/git/c10n/dayjs/node_modules/karma/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"


> spawn-sync@1.0.15 postinstall /home/ts/git/c10n/dayjs/node_modules/spawn-sync
> node postinstall


> sauce-connect-launcher@1.3.2 postinstall /home/ts/git/c10n/dayjs/node_modules/sauce-connect-launcher
> node scripts/install.js || nodejs scripts/install.js

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN notsup Unsupported engine for watchpack-chokidar2@2.0.0: wanted: {"node":"<8.10.0"} (current: {"node":"12.18.3","npm":"6.14.8"})
npm WARN notsup Not compatible with your version of node/npm: watchpack-chokidar2@2.0.0
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/watchpack/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN rollup-plugin-babel@4.4.0 requires a peer of rollup@>=0.60.0 <3 but none is installed. You must install peer dependencies yourself.

added 1415 packages from 1054 contributors in 313.284s

31 packages are looking for funding
  run `npm fund` for details
```
</details>

<details>
   <summary><code>npm test</code></summary>

```bash
$ npm test

> dayjs@0.0.0-development test /home/ts/git/c10n/dayjs
> TZ=Pacific/Auckland npm run test-tz && TZ=Europe/London npm run test-tz && TZ=America/Whitehorse npm run test-tz && npm run test-tz && jest


> dayjs@0.0.0-development test-tz /home/ts/git/c10n/dayjs
> date && jest test/timezone.test --coverage=false

Wed 16 Sep 22:01:22 NZST 2020
 PASS  test/timezone.test.js
  ✓ Add Time days (DST) (29ms)
  ✓ Utc Offset (2ms)
  ✓ Diff (DST) (25ms)
  ✓ UTC add day in DST (5ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        6.495s
Ran all test suites matching /test\/timezone.test/i.

> dayjs@0.0.0-development test-tz /home/ts/git/c10n/dayjs
> date && jest test/timezone.test --coverage=false

Wed 16 Sep 11:01:31 BST 2020
 PASS  test/timezone.test.js
  ✓ Add Time days (DST) (20ms)
  ✓ Utc Offset (1ms)
  ✓ Diff (DST) (17ms)
  ✓ UTC add day in DST (5ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.79s, estimated 4s
Ran all test suites matching /test\/timezone.test/i.

> dayjs@0.0.0-development test-tz /home/ts/git/c10n/dayjs
> date && jest test/timezone.test --coverage=false

Wed 16 Sep 03:01:34 MST 2020
 PASS  test/timezone.test.js
  ✓ Add Time days (DST) (39ms)
  ✓ Utc Offset (3ms)
  ✓ Diff (DST) (25ms)
  ✓ UTC add day in DST (6ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        2.443s
Ran all test suites matching /test\/timezone.test/i.

> dayjs@0.0.0-development test-tz /home/ts/git/c10n/dayjs
> date && jest test/timezone.test --coverage=false

Wed 16 Sep 12:01:38 CEST 2020
 PASS  test/timezone.test.js
  ✓ Add Time days (DST) (38ms)
  ✓ Utc Offset (2ms)
  ✓ Diff (DST) (23ms)
  ✓ UTC add day in DST (6ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        2.797s
Ran all test suites matching /test\/timezone.test/i.
 PASS  test/plugin/isBetween.test.js (16.429s)
 PASS  test/plugin/isSameOrBefore.test.js (17.25s)
 PASS  test/comparison.test.js (18.218s)
 PASS  test/plugin/isSameOrAfter.test.js
 PASS  test/display.test.js
 PASS  test/plugin/objectSupport.test.js
 PASS  test/plugin/customParseFormat.test.js
 PASS  test/plugin/utc.test.js
 FAIL  test/plugin/timezone.test.js
  ● DST, a time that never existed Spring Forward › 2012-03-11 01:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T01:59:59-05:00"
    Received:
      "2012-03-11T00:59:59-05:00"

      122 |     const d = dayjs.tz(s, NY)
      123 |     const m = moment.tz(s, NY)
    > 124 |     expect(d.format()).toBe('2012-03-11T01:59:59-05:00')
      125 |     expect(d.format()).toBe(m.format())
      126 |     expect(d.utcOffset()).toBe(-300)
      127 |     expect(d.utcOffset()).toBe(m.utcOffset())
      
      at Object.<anonymous> (test/plugin/timezone.test.js:124:24)

  ● DST, a time that never existed Spring Forward › 2012-03-11 02:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T03:00:00-04:00"
    Received:
      "2012-03-11T02:00:00-04:00"

      133 |     const d = dayjs.tz(s, NY)
      134 |     const m = moment.tz(s, NY)
    > 135 |     expect(d.format()).toBe('2012-03-11T03:00:00-04:00')
      136 |     expect(d.format()).toBe(m.format())
      137 |     expect(d.valueOf()).toBe(m.valueOf())
      138 |     expect(d.valueOf()).toBe(1331449200000)
      
      at Object.<anonymous> (test/plugin/timezone.test.js:135:24)

  ● DST, a time that never existed Spring Forward › 2012-03-11 02:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T03:59:59-04:00"
    Received:
      "2012-03-11T02:59:59-04:00"

      144 |     const d = dayjs.tz(s, NY)
      145 |     const m = moment.tz(s, NY)
    > 146 |     expect(d.format()).toBe('2012-03-11T03:59:59-04:00')
      147 |     expect(d.format()).toBe(m.format())
      148 |     expect(d.valueOf()).toBe(m.valueOf())
      149 |     expect(d.valueOf()).toBe(1331452799000)
      
      at Object.<anonymous> (test/plugin/timezone.test.js:146:24)

  ● DST, a time that never existed Spring Forward › 2012-03-11 03:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T03:00:00-04:00"
    Received:
      "2012-03-11T02:00:00-04:00"

      155 |     const d = dayjs.tz(s, NY)
      156 |     const m = moment.tz(s, NY)
    > 157 |     expect(d.format()).toBe('2012-03-11T03:00:00-04:00')
      158 |     expect(d.format()).toBe(m.format())
      159 |     expect(d.valueOf()).toBe(m.valueOf())
      160 |     expect(d.valueOf()).toBe(1331449200000)
      
      at Object.<anonymous> (test/plugin/timezone.test.js:157:24)

  ● DST, a time that never existed Fall Back › 2012-11-04 00:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T00:59:59-04:00"
    Received:
      "2012-11-03T23:59:59-04:00"

      171 |     [dayjs, moment].forEach((_) => {
      172 |       const d = _.tz(s, NY)
    > 173 |       expect(d.format()).toBe('2012-11-04T00:59:59-04:00')
      174 |       expect(d.utcOffset()).toBe(-240)
      175 |       expect(d.valueOf()).toBe(1352005199000)
      176 |     })
      
      at forEach (test/plugin/timezone.test.js:173:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:171:21)

  ● DST, a time that never existed Fall Back › 2012-11-04 01:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T01:00:00-04:00"
    Received:
      "2012-11-04T00:00:00-04:00"

      180 |     [dayjs, moment].forEach((_) => {
      181 |       const d = _.tz(s, NY)
    > 182 |       expect(d.format()).toBe('2012-11-04T01:00:00-04:00')
      183 |       expect(d.utcOffset()).toBe(-240)
      184 |       expect(d.valueOf()).toBe(1352005200000)
      185 |     })
      
      at forEach (test/plugin/timezone.test.js:182:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:180:21)

  ● DST, a time that never existed Fall Back › 2012-11-04 01:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T01:59:59-04:00"
    Received:
      "2012-11-04T00:59:59-04:00"

      189 |     [dayjs, moment].forEach((_) => {
      190 |       const d = _.tz(s, NY)
    > 191 |       expect(d.format()).toBe('2012-11-04T01:59:59-04:00')
      192 |       expect(d.utcOffset()).toBe(-240)
      193 |       expect(d.valueOf()).toBe(1352008799000)
      194 |     })
      
      at forEach (test/plugin/timezone.test.js:191:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:189:21)

  ● DST, a time that never existed Fall Back › 2012-11-04 02:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T02:00:00-05:00"
    Received:
      "2012-11-04T01:00:00-05:00"

      198 |     [dayjs, moment].forEach((_) => {
      199 |       const d = _.tz(s, NY)
    > 200 |       expect(d.format()).toBe('2012-11-04T02:00:00-05:00')
      201 |       expect(d.utcOffset()).toBe(-300)
      202 |       expect(d.valueOf()).toBe(1352012400000)
      203 |     })
      
      at forEach (test/plugin/timezone.test.js:200:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:198:21)

 PASS  test/parse.test.js
 FAIL  test/plugin/utc-utcOffset.test.js
  ● change hours when changing the utc offset in UTC mode

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      5
    Received:
      4

      87 |   expect(d.hour()).toBe(6)
      88 |   expect(d.utcOffset(0).hour()).toBe(6)
    > 89 |   expect(d.utcOffset(-60).hour()).toBe(5)
      90 |   expect(d.utcOffset(60).hour()).toBe(7)
      91 |   expect(d.utcOffset(-30).format('HH:mm')).toBe('06:01')
      92 |   expect(d.utcOffset(30).format('HH:mm')).toBe('07:01')
      
      at Object.<anonymous> (test/plugin/utc-utcOffset.test.js:89:35)

  ● keep hours when adding month in offset mode

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      6
    Received:
      5

      111 |   const dm8 = dayjs('2000-01-30T06:31:00-08:00').utcOffset(-8)
      112 | 
    > 113 |   expect(d10.add(1, 'month').hour()).toBe(6)
      114 |   expect(dm8.add(1, 'month').hour()).toBe(6)
      115 | 
      116 |   expect(d10.add(-2, 'month').hour()).toBe(6)
      
      at Object.<anonymous> (test/plugin/utc-utcOffset.test.js:113:38)

 PASS  test/plugin/isoWeek.test.js
 PASS  test/plugin/duration.test.js
 PASS  test/plugin/pluralGetSet.test.js
 PASS  test/get-set.test.js
 PASS  test/plugin/badMutable.test.js
 PASS  test/plugin/relativeTime.test.js
 PASS  test/locale.test.js
 PASS  test/manipulate.test.js
 PASS  test/plugin/localeData.test.js
 PASS  test/plugin/calendar.test.js
 PASS  test/plugin/localizedFormat.test.js
 PASS  test/plugin/advancedFormat.test.js
 PASS  test/plugin/updateLocale.test.js
 PASS  test/locale/uk.test.js
 PASS  test/plugin/quarterOfYear.test.js
 PASS  test/locale/pl.test.js
 PASS  test/plugin/weekday.test.js
 PASS  test/plugin/weekOfYear.test.js
 PASS  test/utils.test.js
 PASS  test/locale/ru.test.js
 PASS  test/plugin/dayOfYear.test.js
 PASS  test/locale/fi.test.js
 PASS  test/locale/cs.test.js
 PASS  test/plugin/minMax.test.js
 PASS  test/locale/sk.test.js
 PASS  test/query.test.js
 PASS  test/locale/et.test.js
 PASS  test/plugin/buddhistEra.test.js
 PASS  test/plugin.test.js
 PASS  test/plugin/isoWeeksInYear.test.js
 PASS  test/locale/en.test.js
 PASS  test/locale/hr.test.js
 PASS  test/plugin/weekYear.test.js
 PASS  test/locale/lt.test.js
 PASS  test/locale/sv.test.js
 PASS  test/locale/zh.test.js
 PASS  test/locale/zh-cn.test.js
 PASS  test/plugin/isTomorrow.test.js
 PASS  test/plugin/isLeapYear.test.js
 PASS  test/plugin/isYesterday.test.js
 PASS  test/plugin/isToday.test.js
 PASS  test/plugin/toObject.test.js
 PASS  test/plugin/isMoment.test.js
 PASS  test/plugin/toArray.test.js
 PASS  test/plugin/declarations.test.js
 PASS  test/constructor.test.js
 PASS  test/timezone.test.js
 PASS  test/locale/keys.test.js (8.178s)
------------------------------|----------|----------|----------|----------|-------------------|
File                          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
------------------------------|----------|----------|----------|----------|-------------------|
All files                     |      100 |    99.65 |      100 |      100 |                   |
 src                          |      100 |      100 |      100 |      100 |                   |
  constant.js                 |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
  utils.js                    |      100 |      100 |      100 |      100 |                   |
 src/locale                   |      100 |      100 |      100 |      100 |                   |
  af.js                       |      100 |      100 |      100 |      100 |                   |
  am.js                       |      100 |      100 |      100 |      100 |                   |
  ar-dz.js                    |      100 |      100 |      100 |      100 |                   |
  ar-kw.js                    |      100 |      100 |      100 |      100 |                   |
  ar-ly.js                    |      100 |      100 |      100 |      100 |                   |
  ar-ma.js                    |      100 |      100 |      100 |      100 |                   |
  ar-sa.js                    |      100 |      100 |      100 |      100 |                   |
  ar-tn.js                    |      100 |      100 |      100 |      100 |                   |
  ar.js                       |      100 |      100 |      100 |      100 |                   |
  az.js                       |      100 |      100 |      100 |      100 |                   |
  be.js                       |      100 |      100 |      100 |      100 |                   |
  bg.js                       |      100 |      100 |      100 |      100 |                   |
  bi.js                       |      100 |      100 |      100 |      100 |                   |
  bm.js                       |      100 |      100 |      100 |      100 |                   |
  bn.js                       |      100 |      100 |      100 |      100 |                   |
  bo.js                       |      100 |      100 |      100 |      100 |                   |
  br.js                       |      100 |      100 |      100 |      100 |                   |
  bs.js                       |      100 |      100 |      100 |      100 |                   |
  ca.js                       |      100 |      100 |      100 |      100 |                   |
  cs.js                       |      100 |      100 |      100 |      100 |                   |
  cv.js                       |      100 |      100 |      100 |      100 |                   |
  cy.js                       |      100 |      100 |      100 |      100 |                   |
  da.js                       |      100 |      100 |      100 |      100 |                   |
  de-at.js                    |      100 |      100 |      100 |      100 |                   |
  de-ch.js                    |      100 |      100 |      100 |      100 |                   |
  de.js                       |      100 |      100 |      100 |      100 |                   |
  dv.js                       |      100 |      100 |      100 |      100 |                   |
  el.js                       |      100 |      100 |      100 |      100 |                   |
  en-SG.js                    |      100 |      100 |      100 |      100 |                   |
  en-au.js                    |      100 |      100 |      100 |      100 |                   |
  en-ca.js                    |      100 |      100 |      100 |      100 |                   |
  en-gb.js                    |      100 |      100 |      100 |      100 |                   |
  en-ie.js                    |      100 |      100 |      100 |      100 |                   |
  en-il.js                    |      100 |      100 |      100 |      100 |                   |
  en-in.js                    |      100 |      100 |      100 |      100 |                   |
  en-nz.js                    |      100 |      100 |      100 |      100 |                   |
  en-tt.js                    |      100 |      100 |      100 |      100 |                   |
  en.js                       |      100 |      100 |      100 |      100 |                   |
  eo.js                       |      100 |      100 |      100 |      100 |                   |
  es-do.js                    |      100 |      100 |      100 |      100 |                   |
  es-pr.js                    |      100 |      100 |      100 |      100 |                   |
  es-us.js                    |      100 |      100 |      100 |      100 |                   |
  es.js                       |      100 |      100 |      100 |      100 |                   |
  et.js                       |      100 |      100 |      100 |      100 |                   |
  eu.js                       |      100 |      100 |      100 |      100 |                   |
  fa.js                       |      100 |      100 |      100 |      100 |                   |
  fi.js                       |      100 |      100 |      100 |      100 |                   |
  fo.js                       |      100 |      100 |      100 |      100 |                   |
  fr-ca.js                    |      100 |      100 |      100 |      100 |                   |
  fr-ch.js                    |      100 |      100 |      100 |      100 |                   |
  fr.js                       |      100 |      100 |      100 |      100 |                   |
  fy.js                       |      100 |      100 |      100 |      100 |                   |
  ga.js                       |      100 |      100 |      100 |      100 |                   |
  gd.js                       |      100 |      100 |      100 |      100 |                   |
  gl.js                       |      100 |      100 |      100 |      100 |                   |
  gom-latn.js                 |      100 |      100 |      100 |      100 |                   |
  gu.js                       |      100 |      100 |      100 |      100 |                   |
  he.js                       |      100 |      100 |      100 |      100 |                   |
  hi.js                       |      100 |      100 |      100 |      100 |                   |
  hr.js                       |      100 |      100 |      100 |      100 |                   |
  ht.js                       |      100 |      100 |      100 |      100 |                   |
  hu.js                       |      100 |      100 |      100 |      100 |                   |
  hy-am.js                    |      100 |      100 |      100 |      100 |                   |
  id.js                       |      100 |      100 |      100 |      100 |                   |
  is.js                       |      100 |      100 |      100 |      100 |                   |
  it-ch.js                    |      100 |      100 |      100 |      100 |                   |
  it.js                       |      100 |      100 |      100 |      100 |                   |
  ja.js                       |      100 |      100 |      100 |      100 |                   |
  jv.js                       |      100 |      100 |      100 |      100 |                   |
  ka.js                       |      100 |      100 |      100 |      100 |                   |
  kk.js                       |      100 |      100 |      100 |      100 |                   |
  km.js                       |      100 |      100 |      100 |      100 |                   |
  kn.js                       |      100 |      100 |      100 |      100 |                   |
  ko.js                       |      100 |      100 |      100 |      100 |                   |
  ku.js                       |      100 |      100 |      100 |      100 |                   |
  ky.js                       |      100 |      100 |      100 |      100 |                   |
  lb.js                       |      100 |      100 |      100 |      100 |                   |
  lo.js                       |      100 |      100 |      100 |      100 |                   |
  lt.js                       |      100 |      100 |      100 |      100 |                   |
  lv.js                       |      100 |      100 |      100 |      100 |                   |
  me.js                       |      100 |      100 |      100 |      100 |                   |
  mi.js                       |      100 |      100 |      100 |      100 |                   |
  mk.js                       |      100 |      100 |      100 |      100 |                   |
  ml.js                       |      100 |      100 |      100 |      100 |                   |
  mn.js                       |      100 |      100 |      100 |      100 |                   |
  mr.js                       |      100 |      100 |      100 |      100 |                   |
  ms-my.js                    |      100 |      100 |      100 |      100 |                   |
  ms.js                       |      100 |      100 |      100 |      100 |                   |
  mt.js                       |      100 |      100 |      100 |      100 |                   |
  my.js                       |      100 |      100 |      100 |      100 |                   |
  nb.js                       |      100 |      100 |      100 |      100 |                   |
  ne.js                       |      100 |      100 |      100 |      100 |                   |
  nl-be.js                    |      100 |      100 |      100 |      100 |                   |
  nl.js                       |      100 |      100 |      100 |      100 |                   |
  nn.js                       |      100 |      100 |      100 |      100 |                   |
  oc-lnc.js                   |      100 |      100 |      100 |      100 |                   |
  pa-in.js                    |      100 |      100 |      100 |      100 |                   |
  pl.js                       |      100 |      100 |      100 |      100 |                   |
  pt-br.js                    |      100 |      100 |      100 |      100 |                   |
  pt.js                       |      100 |      100 |      100 |      100 |                   |
  ro.js                       |      100 |      100 |      100 |      100 |                   |
  ru.js                       |      100 |      100 |      100 |      100 |                   |
  rw.js                       |      100 |      100 |      100 |      100 |                   |
  sd.js                       |      100 |      100 |      100 |      100 |                   |
  se.js                       |      100 |      100 |      100 |      100 |                   |
  si.js                       |      100 |      100 |      100 |      100 |                   |
  sk.js                       |      100 |      100 |      100 |      100 |                   |
  sl.js                       |      100 |      100 |      100 |      100 |                   |
  sq.js                       |      100 |      100 |      100 |      100 |                   |
  sr-cyrl.js                  |      100 |      100 |      100 |      100 |                   |
  sr.js                       |      100 |      100 |      100 |      100 |                   |
  ss.js                       |      100 |      100 |      100 |      100 |                   |
  sv.js                       |      100 |      100 |      100 |      100 |                   |
  sw.js                       |      100 |      100 |      100 |      100 |                   |
  ta.js                       |      100 |      100 |      100 |      100 |                   |
  te.js                       |      100 |      100 |      100 |      100 |                   |
  tet.js                      |      100 |      100 |      100 |      100 |                   |
  tg.js                       |      100 |      100 |      100 |      100 |                   |
  th.js                       |      100 |      100 |      100 |      100 |                   |
  tk.js                       |      100 |      100 |      100 |      100 |                   |
  tl-ph.js                    |      100 |      100 |      100 |      100 |                   |
  tlh.js                      |      100 |      100 |      100 |      100 |                   |
  tr.js                       |      100 |      100 |      100 |      100 |                   |
  tzl.js                      |      100 |      100 |      100 |      100 |                   |
  tzm-latn.js                 |      100 |      100 |      100 |      100 |                   |
  tzm.js                      |      100 |      100 |      100 |      100 |                   |
  ug-cn.js                    |      100 |      100 |      100 |      100 |                   |
  uk.js                       |      100 |      100 |      100 |      100 |                   |
  ur.js                       |      100 |      100 |      100 |      100 |                   |
  uz-latn.js                  |      100 |      100 |      100 |      100 |                   |
  uz.js                       |      100 |      100 |      100 |      100 |                   |
  vi.js                       |      100 |      100 |      100 |      100 |                   |
  x-pseudo.js                 |      100 |      100 |      100 |      100 |                   |
  yo.js                       |      100 |      100 |      100 |      100 |                   |
  zh-cn.js                    |      100 |      100 |      100 |      100 |                   |
  zh-hk.js                    |      100 |      100 |      100 |      100 |                   |
  zh-tw.js                    |      100 |      100 |      100 |      100 |                   |
  zh.js                       |      100 |      100 |      100 |      100 |                   |
 src/plugin/advancedFormat    |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/badMutable        |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/buddhistEra       |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/calendar          |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/customParseFormat |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/dayOfYear         |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/duration          |      100 |    96.23 |      100 |      100 |                   |
  index.js                    |      100 |    96.23 |      100 |      100 |            63,109 |
 src/plugin/isBetween         |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isLeapYear        |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isMoment          |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isSameOrAfter     |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isSameOrBefore    |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isToday           |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isTomorrow        |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isYesterday       |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isoWeek           |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/isoWeeksInYear    |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/localeData        |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/localizedFormat   |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/minMax            |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/objectSupport     |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/pluralGetSet      |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/quarterOfYear     |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/relativeTime      |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/timezone          |      100 |    92.86 |      100 |      100 |                   |
  index.js                    |      100 |    92.86 |      100 |      100 |                41 |
 src/plugin/toArray           |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/toObject          |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/updateLocale      |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/utc               |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/weekOfYear        |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/weekYear          |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
 src/plugin/weekday           |      100 |      100 |      100 |      100 |                   |
  index.js                    |      100 |      100 |      100 |      100 |                   |
------------------------------|----------|----------|----------|----------|-------------------|
Handlebars: Access has been denied to resolve the property "statements" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "branches" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "functions" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "lines" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details

Summary of all failing tests
 FAIL  test/plugin/timezone.test.js
  ● DST, a time that never existed Spring Forward › 2012-03-11 01:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T01:59:59-05:00"
    Received:
      "2012-03-11T00:59:59-05:00"

      122 |     const d = dayjs.tz(s, NY)
      123 |     const m = moment.tz(s, NY)
    > 124 |     expect(d.format()).toBe('2012-03-11T01:59:59-05:00')
      125 |     expect(d.format()).toBe(m.format())
      126 |     expect(d.utcOffset()).toBe(-300)
      127 |     expect(d.utcOffset()).toBe(m.utcOffset())
      
      at Object.<anonymous> (test/plugin/timezone.test.js:124:24)

  ● DST, a time that never existed Spring Forward › 2012-03-11 02:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T03:00:00-04:00"
    Received:
      "2012-03-11T02:00:00-04:00"

      133 |     const d = dayjs.tz(s, NY)
      134 |     const m = moment.tz(s, NY)
    > 135 |     expect(d.format()).toBe('2012-03-11T03:00:00-04:00')
      136 |     expect(d.format()).toBe(m.format())
      137 |     expect(d.valueOf()).toBe(m.valueOf())
      138 |     expect(d.valueOf()).toBe(1331449200000)
      
      at Object.<anonymous> (test/plugin/timezone.test.js:135:24)

  ● DST, a time that never existed Spring Forward › 2012-03-11 02:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T03:59:59-04:00"
    Received:
      "2012-03-11T02:59:59-04:00"

      144 |     const d = dayjs.tz(s, NY)
      145 |     const m = moment.tz(s, NY)
    > 146 |     expect(d.format()).toBe('2012-03-11T03:59:59-04:00')
      147 |     expect(d.format()).toBe(m.format())
      148 |     expect(d.valueOf()).toBe(m.valueOf())
      149 |     expect(d.valueOf()).toBe(1331452799000)
      
      at Object.<anonymous> (test/plugin/timezone.test.js:146:24)

  ● DST, a time that never existed Spring Forward › 2012-03-11 03:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-03-11T03:00:00-04:00"
    Received:
      "2012-03-11T02:00:00-04:00"

      155 |     const d = dayjs.tz(s, NY)
      156 |     const m = moment.tz(s, NY)
    > 157 |     expect(d.format()).toBe('2012-03-11T03:00:00-04:00')
      158 |     expect(d.format()).toBe(m.format())
      159 |     expect(d.valueOf()).toBe(m.valueOf())
      160 |     expect(d.valueOf()).toBe(1331449200000)
      
      at Object.<anonymous> (test/plugin/timezone.test.js:157:24)

  ● DST, a time that never existed Fall Back › 2012-11-04 00:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T00:59:59-04:00"
    Received:
      "2012-11-03T23:59:59-04:00"

      171 |     [dayjs, moment].forEach((_) => {
      172 |       const d = _.tz(s, NY)
    > 173 |       expect(d.format()).toBe('2012-11-04T00:59:59-04:00')
      174 |       expect(d.utcOffset()).toBe(-240)
      175 |       expect(d.valueOf()).toBe(1352005199000)
      176 |     })
      
      at forEach (test/plugin/timezone.test.js:173:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:171:21)

  ● DST, a time that never existed Fall Back › 2012-11-04 01:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T01:00:00-04:00"
    Received:
      "2012-11-04T00:00:00-04:00"

      180 |     [dayjs, moment].forEach((_) => {
      181 |       const d = _.tz(s, NY)
    > 182 |       expect(d.format()).toBe('2012-11-04T01:00:00-04:00')
      183 |       expect(d.utcOffset()).toBe(-240)
      184 |       expect(d.valueOf()).toBe(1352005200000)
      185 |     })
      
      at forEach (test/plugin/timezone.test.js:182:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:180:21)

  ● DST, a time that never existed Fall Back › 2012-11-04 01:59:59

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T01:59:59-04:00"
    Received:
      "2012-11-04T00:59:59-04:00"

      189 |     [dayjs, moment].forEach((_) => {
      190 |       const d = _.tz(s, NY)
    > 191 |       expect(d.format()).toBe('2012-11-04T01:59:59-04:00')
      192 |       expect(d.utcOffset()).toBe(-240)
      193 |       expect(d.valueOf()).toBe(1352008799000)
      194 |     })
      
      at forEach (test/plugin/timezone.test.js:191:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:189:21)

  ● DST, a time that never existed Fall Back › 2012-11-04 02:00:00

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      "2012-11-04T02:00:00-05:00"
    Received:
      "2012-11-04T01:00:00-05:00"

      198 |     [dayjs, moment].forEach((_) => {
      199 |       const d = _.tz(s, NY)
    > 200 |       expect(d.format()).toBe('2012-11-04T02:00:00-05:00')
      201 |       expect(d.utcOffset()).toBe(-300)
      202 |       expect(d.valueOf()).toBe(1352012400000)
      203 |     })
      
      at forEach (test/plugin/timezone.test.js:200:26)
          at Array.forEach (<anonymous>)
      at Object.<anonymous> (test/plugin/timezone.test.js:198:21)

 FAIL  test/plugin/utc-utcOffset.test.js
  ● change hours when changing the utc offset in UTC mode

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      5
    Received:
      4

      87 |   expect(d.hour()).toBe(6)
      88 |   expect(d.utcOffset(0).hour()).toBe(6)
    > 89 |   expect(d.utcOffset(-60).hour()).toBe(5)
      90 |   expect(d.utcOffset(60).hour()).toBe(7)
      91 |   expect(d.utcOffset(-30).format('HH:mm')).toBe('06:01')
      92 |   expect(d.utcOffset(30).format('HH:mm')).toBe('07:01')
      
      at Object.<anonymous> (test/plugin/utc-utcOffset.test.js:89:35)

  ● keep hours when adding month in offset mode

    expect(received).toBe(expected) // Object.is equality
    
    Expected value to be:
      6
    Received:
      5

      111 |   const dm8 = dayjs('2000-01-30T06:31:00-08:00').utcOffset(-8)
      112 | 
    > 113 |   expect(d10.add(1, 'month').hour()).toBe(6)
      114 |   expect(dm8.add(1, 'month').hour()).toBe(6)
      115 | 
      116 |   expect(d10.add(-2, 'month').hour()).toBe(6)
      
      at Object.<anonymous> (test/plugin/utc-utcOffset.test.js:113:38)


Test Suites: 2 failed, 57 passed, 59 total
Tests:       10 failed, 554 passed, 564 total
Snapshots:   0 total
Time:        41.74s
Ran all test suites.
npm ERR! Test failed.  See above for more details.
```
</details>
Oh, I see. Because of DST, some of the tests failed because of a fixed datetime string 

Patch:
diff --git a/src/index.js b/src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,6 @@
 import * as C from './constant'
-import U from './utils'
 import en from './locale/en'
+import U from './utils'
 
 let L = 'en' // global locale
 const Ls = {} // global loaded locale
@@ -43,6 +43,7 @@ const wrapper = (date, instance) =>
   dayjs(date, {
     locale: instance.$L,
     utc: instance.$u,
+    x: instance.$x,
     $offset: instance.$offset // todo: refactor; do not use this.$offset in you code
   })
 
@@ -81,6 +82,7 @@ class Dayjs {
 
   parse(cfg) {
     this.$d = parseDate(cfg)
+    this.$x = cfg.x || {}
     this.init()
   }
 
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
@@ -1,7 +1,6 @@
 import { MILLISECONDS_A_MINUTE, MIN } from '../../constant'
 
 export default (option, Dayjs, dayjs) => {
-  const localOffset = (new Date()).getTimezoneOffset()
   const proto = Dayjs.prototype
   dayjs.utc = function (date) {
     const cfg = { date, utc: true, args: arguments } // eslint-disable-line prefer-rest-params
@@ -64,8 +63,11 @@ export default (option, Dayjs, dayjs) => {
       return ins
     }
     if (input !== 0) {
-      ins = this.local().add(offset + localOffset, MIN)
+      const localTimezoneOffset = this.$u
+        ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset()
+      ins = this.local().add(offset + localTimezoneOffset, MIN)
       ins.$offset = offset
+      ins.$x.$localOffset = localTimezoneOffset
     } else {
       ins = this.utc()
     }
@@ -81,7 +83,7 @@ export default (option, Dayjs, dayjs) => {
 
   proto.valueOf = function () {
     const addedOffset = !this.$utils().u(this.$offset)
-      ? this.$offset + localOffset : 0
+      ? this.$offset + (this.$x.$localOffset || (new Date()).getTimezoneOffset()) : 0
     return this.$d.valueOf() - (addedOffset * MILLISECONDS_A_MINUTE)
   }
 


Test patch:
diff --git a/test/timezone.test.js b/test/timezone.test.js
--- a/test/timezone.test.js
+++ b/test/timezone.test.js
@@ -1,5 +1,5 @@
-import moment from 'moment'
 import MockDate from 'mockdate'
+import moment from 'moment'
 import dayjs from '../src'
 import utc from '../src/plugin/utc'
 
@@ -54,3 +54,11 @@ it('UTC add day in DST', () => {
     .toBe(momentTest.clone().add(2, 'day').format())
 })
 
+it('UTC and utcOffset', () => {
+  const test1 = 1331449199000 // 2012/3/11 14:59:59
+  expect(moment(test1).utcOffset(-300).format())
+    .toBe(dayjs(test1).utcOffset(-300).format())
+  const test2 = '2000-01-01T06:31:00Z'
+  expect(moment.utc(test2).utcOffset(-60).format())
+    .toBe(dayjs.utc(test2).utcOffset(-60).format())
+})