iamkun / dayjs

⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
https://day.js.org
MIT License
46.71k stars 2.28k forks source link

Add Latin locale #961

Open tukusejssirs opened 4 years ago

tukusejssirs commented 4 years ago

For 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?
weekdays: 'Dominica-feria secunda-feria tertia-feria quarta-feria quinta-feria sexta-Sabbato'.split('-'),

  1. There’s a subissue: in Latin, there are two different ways to name the weekdays, 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):

B. using ferias (numbering days, starting with 1 for Sunday):

C. variation of the feria names, used in the RC Church (uses Dominica for Sunday and Sabbato for Saturday):

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?


  1. Weekday names: when the feria names are used, one may shorten it by using Roman numerals (e.g. feria sextafera 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.

  1. 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?

  1. 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?
iamkun commented 4 years ago
  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

tukusejssirs commented 4 years ago
  1. 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.

  2. Okay.

  3. 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?


  1. Country and lang codes. la is code for Latin according to ISO 369-2. However, I believe that country code system you use is ISO 3166-1 alpha-2, which assigns VA for Vatican / the Holy See.
iamkun commented 4 years ago

2 the best way might just be simple copy-paste.

Yes, you have to create a function to make the conversion in locale file.

tukusejssirs commented 4 years ago

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 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:
const dayjs = require('./dayjs.min.js');
dayjs.locale('la')

var l = dayjs.locale()

console.log(l)
  1. 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, but adding require('dayjs/locale/la') throwed the following error:

$ 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.

tukusejssirs commented 4 years ago

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.

iamkun commented 4 years ago

I would manually change 'dayjs/locale/la' to '../src/locale/la' 😢

tukusejssirs commented 4 years ago

I would manually change 'dayjs/locale/la' to '../src/locale/la' cry

Where would you do that?

iamkun commented 4 years ago

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'

tukusejssirs commented 4 years ago

I have tried out your suggestion, but it still does not work, see below. All my scripts are located in the repo root.

node testLa2.js (with require) 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. (/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) ```
node testLa2.mjs (with require) 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) ```
node testLa2.js (with import) 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 ```
node testLa2.mjs (with import) 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. (internal/modules/esm/module_job.js:47:40) at link (internal/modules/esm/module_job.js:46:36) { code: 'ERR_MODULE_NOT_FOUND' } ```
iamkun commented 4 years ago

please use npm test to test the source code

tukusejssirs commented 4 years ago

Indeed, you’re right, there are failing tests, but I did not change anything in those files.

Failing tests ```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. (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. (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. (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 () 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. (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. ```
iamkun commented 4 years ago

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.

tukusejssirs commented 4 years ago

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.

iamkun commented 4 years ago

I'll try CET to see if I can reproduce this later.

tukusejssirs commented 4 years ago

@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.

npm install ```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 ```
npm test ```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. (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. (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. (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. (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 () at Object. (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 () at Object. (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 () at Object. (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 () at Object. (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. (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. (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. (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. (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. (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. (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 () at Object. (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 () at Object. (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 () at Object. (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 () at Object. (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. (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. (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. ```
iamkun commented 4 years ago

Oh, I see. Because of DST, some of the tests failed because of a fixed datetime string

iamkun commented 4 years ago

Hi, @tukusejssirs

I have made a pr https://github.com/iamkun/dayjs/pull/1053 to fix this issue.

Can you please help me test it to see if it works?

tukusejssirs commented 4 years ago

@iamkun, I still have no idea why all the above-mentioned test scripts of mine fail to use la and return the desired values.

I have run npm install && npm test && npm run build to build to library (dayjs.min.js), but it does not contain the Latin locale (why? what additional steps are required to get the Latin locale into the library?).

Also if I import or require ./src/locale/la.js (or ./src/locale/la) in the script, it always fails; either because of the import statement in the la.js file (while the script has .js extension; error: SyntaxError: Cannot use import statement outside a module) or there is an unexpected token '.' (. meaning the CWD).

I am fairly sure that this are a newbie mistake, but it seams I can’t find it. AFAIK, import statements can be used in the modules or .mjs scripts only, while require in .js scripts.

Thanks for your help.

iamkun commented 4 years ago

you can check this as a reference test/locale/cs.test.js and create a test file to test Latin locale

tukusejssirs commented 4 years ago

I cannot do it the way it is in cs.test.js, because in there, the values are compared with Moment output, while Moment does not include a Latin locale.

I need to do it the way it is in sv.test.js.

Still, I’d like to have test script before I push it to the repo, therefore I wish I could run a script using the dayjs module from src/ folder. For example, in romcal (in F-TypeScriptbranch), I can run node -r ts-node/register -r tsconfig-paths/register romcalTest.ts (while romcalTest.ts is in the repo root folder and CWD is also the repo root folder) and use import romcal from './src'; to use the library without building it for testing purpose. Note that romcal is a TypeScript library.

Note that I could not make import dayjs from './src' work in here, because:

  1. in a .js file, I get the following error: SyntaxError: Cannot use import statement outside a module (which is understandable);
  2. in an .mjs file, I get the following error: Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/home/ts/git/c10n/dayjs_ts/src' is not supported resolving ES modules, imported from /home/ts/git/c10n/dayjs_ts/ttt.mjs (which I don’t understand and am not capable of solving it).

Anyway, I don’t care how this would be solved, as long as I can use dayjs library locally using the files in src/. :smiley:

iamkun commented 4 years ago

What I mean is that you could create a test file named la.test.js, and write any test you want in it (including console.log).

Then just run npm test

tukusejssirs commented 4 years ago

Can you tell me why dayjs('2020-01-01').locale('la').format('LL') outputs LL string? Same for L.

And D. MMMM YYYY outputs 1. ianuarius 2020 instead of 1. ianuarii 2020 (there is a getMonthInGenitive() function which changes the grammar case to genitive); does this mean I need to (re-) define the MMMM in the la.js file?

Update: I needed to add advancedFormat, that is the following to lines into la.test.js

import localizedFormat from '../../src/plugin/localizedFormat'
dayjs.extend(localizedFormat)

But now I receive NamN instead of ianuarii (January in Latin in genitive). For example:

// la.js
LL: ['D ', getMonthInGenitive('MMMM'), ' ', romanise('YYYY')].join(''),

// la.test.js
console.log('testLL : ', dayjs('2020-01-01').locale('la').format('LL'))

// output in `npm test`
testLL :  1  NamN

// expected output in `npm test`
testLL :  1 ianuarii MM

Update 2: One of the problems lays in the argument of romanise() function: I put there YYYY as string; how can I send the year as number? Same would be the problem with the getMonthInGenitive() function, which needs to get the name of the month in Latin in nominative case (one from months key).

tukusejssirs commented 4 years ago

What I mean is that you could create a test file named la.test.js, and write any test you want in it (including console.log).

Then just run npm test

I understand what you mean, but I still want to be able to run a script using dayjs library loaded from src/ folder, because the npm test ways is absolutely slow for my needs. I want to test each and every definition in la.js by hand before I put it into la.test.js. Reason? I don’t trust myself in this, because I have little to no experience with NPM and creating tests as such. However, I can do it, but I need a way to run dayjs from src/.

iamkun commented 4 years ago

npm test does exactly what you want to test dayjs from src/ live.

It will be better if you could test it your self, cause I don't know much about the getMonthInGenitive function and don't know what's the expected output.

tukusejssirs commented 4 years ago

npm test does exactly what you want to test dayjs from src/ live.

Okay, I see I can’t make you help me with this subissue. :smiley: I’ll run node node_modules/jest/bin/jest.js test/locale/la.test.js --coverage=false then, in order to test my stuff.

It will be better if you could test it your self, cause I don't know much about the getMonthInGenitive function and don't know what's the expected output.

Well, actually I have tested it, but within a separate script (i.e. without using dayjs).

That function is quite simple: it accepts one argument (a month name in Latin in nominative) and returns the genitive form of that month.

The whole problem is that I don’t know how to send it the name of the month in locale.formats.LL. Currently, it returns a string (MMMM), not the name of the month (e.g. ianuarius). Can you help with this please?

PS—I don’t even understand, how the translate funtcion from cs.js gets its arguments. in locale.relativeTime, no argument is supplied. Maybe if you make me understand this, I might be able to make it work.

iamkun commented 4 years ago

If I understand you correctly, https://day.js.org/docs/en/customization/relative-time#additional-token-processing is what you are looking for about locale.relativeTime in cs.js.

tukusejssirs commented 4 years ago

If I understand you correctly, https://day.js.org/docs/en/customization/relative-time#additional-token-processing is what you are looking for about locale.relativeTime in cs.js.

That might work, however, does it work with locale.formats too? The link from the docs you shared with me states it works with locale.relativeTime; it does not talk about locale.formats.

iamkun commented 4 years ago

No at this moment.

locale.formats will only do the replacement from 'MMMM' to the corresponding month name from localeObject.months

tukusejssirs commented 4 years ago

Then my functions in la.js won’t at all.

Unless you know of another way. Here is what I need to do with MMMM and YYYY:

  1. For months, I need to return month name in genitive case (i.e. substitute the form in nominative case with one in genitive case). For this I need to know what month is to be output, either as a number (1-12 or 0-11) or month name (e.g. ianuarius for January).

  2. For year: I need to convert the year in Arabic numerals (e.g. 2020) to year in Roman numerals (e.g. MM). For this purpose, we definitely need to process the year (as an int) using the romanise() function.

PS:

iamkun commented 4 years ago

Something you can do is that month name also accepts a function with days instance and format passed in https://day.js.org/docs/en/customization/month-names#additional-token-processing

tukusejssirs commented 4 years ago

Something you can do is that month name also accepts a function with days instance and format passed in https://day.js.org/docs/en/customization/month-names#additional-token-processing

You mean I can replace locale.months with the following code and it’ll work?

months: function (dayjsInstance, format) {
  if (/^MMMM/.test(format)) {
    return 'ianuarius_februarius_martius_aprilis_maius_iunius_iulius_augustus_september_october_november_december'.split('_');
  } else {
    return 'ianuarii_februarii_martii_aprilis_maii_iunii_iulii_augusti_septembris_octobris_novembris_decembris'.split('_');
  }
},

Update: No, it does not. It returns all months in genitive (comman-separated), therefore it is a good step forward, but we ain’t there yet. :smiley:

Update 2: I think I need to know what are the monthShortFormat[dayjsInstance.month()] and monthShortStandalone[dayjsInstance.month()] functions. How should they look like?

Update 3: Nevermind, I’ve fixed it using the code from ru.js (found it via #900) and hr.js.

tukusejssirs commented 4 years ago

Last thing to fix is the conversion of the year from Arabic numerals to Roman numerals. I have a function (romanise()) which accepts a year (as an int) and it works as expected. Can I somehow ‘plug it in’ somewhere?

IMHO, it might a better idea to implement it into dayjs itself and use a kind of flag if one wants to output the year (or month or day of month) in Roman numerals.

For example:

Update: Here’s link to romanise() function.

Update 2: I tried the following code (based on monthStandalone), but it does not work. I presume I can’t use the same logic for years.

const romaniseYear = (dayjsInstance, format) => {
  return romanise(dayjsInstance.year())
}
iamkun commented 4 years ago

I'd prefer it as a separate plugin.

tukusejssirs commented 4 years ago

Is that something you could create and place under plugins/ folder?

iamkun commented 4 years ago

Oh, sorry I just misundertand what you mean.

IMO, just leave this romanise() function in the locale file. That would be enough right now.

tukusejssirs commented 4 years ago

IMO, just leave this romanise() function in the locale file. That would be enough right now.

I’ve no problem with that, however, how can I add the year (as an int) as argument to the function? romanise('YYYY'), obviously, does not work.

Update: Just a reminder: I need to romanise the year in locale.formats, as well as anywhere where the year is requested (i.e. Y+, because AFAIK in Latin, the year is never abbreviated).

iamkun commented 4 years ago

As far as I can tell, seems there is no way to convert year to anything other than the year number.

You may still have to consider making a plugin like buddhistEra to get what you want.

tukusejssirs commented 4 years ago

You may still have to consider making a plugin like buddhistEra to get what you want.

Okay, I’ll do my best.


buddhistEra adds additional date format (BB and BBBB). I am looking for replacing all years (be it YY or YYYY, therefore I think should use YY+ regex) with romanised year. This is a requirement, however, I am not sure, if I can simply replace the year in the dayjs object, because that would change the data type (from int to string). What do you think?

tukusejssirs commented 4 years ago

@iamkun, in case I cannot replace the year in dayjs object, I would choose:

If you disagree with these, let me know.

Anyway, I tried to modify the code in buddhistEra (copied to src/plugin/romanisation; let me know if you disagree with the name of the plugin). Below you can find my currect version of the code.

The thing is, it does not work for some reason. As you can see, I left there console.log('plugin : ', year), which outputs the correct romanised year, but the output of the plugin itself (i.e. replacement of RRRR or RR) is incorrect, e.g. for year 2020 it outputs 0115778332001577833200. I am not sure what it means or how what that number created; I suspect it somehow converts the characters into their hex representation or what.

romanisation ```js import { FORMAT_DEFAULT } from '../../constant' export default (o, c) => { // locale needed later /* eslint-disable */ // src: https://stackoverflow.com/a/9083076 // function romanise(num) { function romanise(num) { if (isNaN(num)) { return NaN } const key = [ '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX' ] const digits = String(+num).split('') let roman = '' let i = 3 while (i--) { roman = (key[+digits.pop() + (i * 10)] || '') + roman } return Array(+digits.join('') + 1).join('M') + roman } /* eslint-enable */ const proto = c.prototype const oldFormat = proto.format // extend en locale here proto.format = function (formatStr) { // const yearBias = 543 const str = formatStr || FORMAT_DEFAULT const result = str.replace(/(\[[^\]]+])|RRRR|RR/g, (match, a) => { const year = romanise(this.$y) console.log('plugin : ', year) const args = [year, year.length] return a || this.$utils().s(...args, '0') }) return oldFormat.bind(this)(result) } }
iamkun commented 4 years ago

@tukusejssirs Is there something we can check as a reference of the format token? like JAVA or something.

And actually, this plugin is becoming much more complex than we expected earlier, and we may release it in a separate repo like https://github.com/alibaba-aero/jalaliday so that you can get better control of the code logic, cause it's difficult for us to maintain these logic.

tukusejssirs commented 4 years ago

@tukusejssirs Is there something we can check as a reference of the format token? like JAVA or something.

No reference, because I couldn’t find any programming language with Roman numerals for year/dom/month implemented. Those date format (R/T/O) are just my attempt to use something what is not used in dayjs yet.

And actually, this plugin is becoming much more complex than we expected earlier, and we may release it in a separate repo like https://github.com/alibaba-aero/jalaliday so that you can get better control of the code logic, cause it's difficult for us to maintain these logic.

If you can guide me … Because I am not an experienced programmer (am I a programmer at all?). All I need is Latin locale for romcal, which use dayjs, therefore I need to implement Latin locale into dayjs. It is mostly done (apart from the tests, which still need some tending), but I need at least the romanised year, which would be ideally placed instead of each year (i.e. YY and YYYY). If that is not possible, I am open to use the same logic as the buddhistEra plugin uses.

[…] cause it's difficult for us to maintain these logic.

May I know what is the difficult part of this logic? :smiley:

iamkun commented 4 years ago

Day.js accepts all PRs related to adding locale. However, as for official plugins, we'd like to keep it in a fixed amount,maybe, just enough to add APIs the same as moment.js. That's why I advice you to to manage this plugin by your own.

tukusejssirs commented 4 years ago

Day.js accepts all PRs related to adding locale. However, as for official plugins, we'd like to keep it in a fixed amount,maybe, just enough to add APIs the same as moment.js. That's why I advice you to to manage this plugin by your own.

Okay, I got it. Just a quick question: therefore there is no way (or intention) to add a plugin for romanisation of the year to the list of the official plugins?

iamkun commented 4 years ago

I don't think we have the ability right now.

tukusejssirs commented 3 years ago

@iamkun, how can I test ordinal numbers? Does it only work with Do (i.e. days of months)? Why does it not work with years (YY and YYYY) and months (M)?

iamkun commented 3 years ago

Yes, ordinal only works for Do at present.

As far as I can see, it's better to make a plugin yourself for the romanization ordinal to get the best result that you expected. Cause it has too much different than other locales that we supported.

tukusejssirs commented 3 years ago

Yes, ordinal only works for Do at present.

Thanks for clarification. :smiley:

Cause it has too much different than other locales that we supported.

Well, indeed you don’t support romanisation at all, but that does not mean that it is not used by real humans. For example, in Hungarian, one can use 2020. X. 2. for 2 Oct 2020 (src). In Latin, the years are always written in Roman numerals and the day of month is sometimes too.

I don’t say that you are required to implement it, but please do consider implementing a flag for this within dayjs codebase. Thanks.

iamkun commented 3 years ago

@tukusejssirs Of course I know it's an important language. However, bundle extra logic to the main pack will significantly increase the bundle size, while the use is limited. In this case like many others, we recommend implementing it as a separate self-maintained plugin to make it fully supported.

forreggbor commented 11 months ago

Yes, ordinal only works for Do at present.

Thanks for clarification. 😃

Cause it has too much different than other locales that we supported.

Well, indeed you don’t support romanisation at all, but that does not mean that it is not used by real humans. For example, in Hungarian, one can use 2020. X. 2. for 2 Oct 2020 (src). In Latin, the years are always written in Roman numerals and the day of month is sometimes too.

I don’t say that you are required to implement it, but please do consider implementing a flag for this within dayjs codebase. Thanks.

It's not true that the Hungarians writing months like XII. We can and allowed but never used. We use number: 1,2,3...12 I'm Hungarian. :-) The page what you linked says that the Hungarians might write the dates in 4 different format but actually we use only the 1st ,2nd and 3rd format. Of course the XII also right and acceptable for december but never used in such way.