diff --git a/.editorconfig b/.editorconfig index 14c1d8c19..d4d73cf57 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,3 +4,4 @@ root = true charset = utf-8 end_of_line = lf insert_final_newline = true +indent_size = 2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..34cbdac9b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,50 @@ +name: Release +on: + workflow_run: + workflows: ['Lint & Unit Test'] + branches: [master] + types: + - completed + +permissions: + contents: read # for checkout + +jobs: + release: + env: + GITHUB_TRIGGER_REF: ${{ github.event.workflow_run.head_branch }} # For workflow_run the GITHUB_REF is the default branch, as mentioned in the docs + if: ${{ github.event.workflow_run.conclusion == 'success' }} + name: Release + runs-on: ubuntu-latest + permissions: + contents: write # to be able to publish a GitHub release + issues: write # to be able to comment on released issues + pull-requests: write # to be able to comment on released pull requests + id-token: write # to enable use of OIDC for npm provenance + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ env.GITHUB_TRIGGER_REF }} + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 'lts/*' # semantic-release requires Node >= 18 + - name: Install dependencies + run: npm clean-install + - name: Build + env: # temporary workaround for "Error: error:0308010C:digital envelope routines::unsupported" in Node lts / 18 + NODE_OPTIONS: --openssl-legacy-provider + run: npm run build && npm run babel + - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies + run: npm audit signatures + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + npm install -g @semantic-release/changelog @semantic-release/git semantic-release + GITHUB_REF=${{ env.GITHUB_TRIGGER_REF }} semantic-release + echo release success + curl -s ${{ secrets.GITEE_SYNC_URL }} diff --git a/.npmignore b/.npmignore index f342d6304..4577b0a50 100644 --- a/.npmignore +++ b/.npmignore @@ -29,3 +29,4 @@ docs .travis.yml karma.sauce.conf.js .github +.releaserc diff --git a/.releaserc b/.releaserc new file mode 100644 index 000000000..8c9fced18 --- /dev/null +++ b/.releaserc @@ -0,0 +1,16 @@ +{ + "branches": ["master"], + "prepare": [ + { + "path": "@semantic-release/changelog" + }, + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md" + ] + } + ] + ] +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b8aba28b2..000000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: node_js -cache: - directories: - - ~/.npm - - node_modules -node_js: - - '18' - - '16' - - '14' - - '12' -install: - - npm install -g codecov - - npm install -script: - - npm run lint - - npm test - - codecov -after_success: - - if [ "$TRAVIS_BRANCH" == "master" ] && [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then - npx travis-deploy-once --pro && npm run build && npm run babel && npm install -g @semantic-release/changelog @semantic-release/git semantic-release && semantic-release && echo release success && curl ${TriggerUrl} && npm run test:sauce; - fi -branches: - only: - - master diff --git a/CHANGELOG.md b/CHANGELOG.md index b0857bc7b..144780498 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,81 @@ +## [1.11.10](https://github.com/iamkun/dayjs/compare/v1.11.9...v1.11.10) (2023-09-19) + + +### Bug Fixes + +* Add Korean Day of Month with ordinal ([#2395](https://github.com/iamkun/dayjs/issues/2395)) ([dd55ee2](https://github.com/iamkun/dayjs/commit/dd55ee2aadd1009242235e47d558bbf028827896)) +* change back fa locale to the Gregorian calendar equivalent ([#2411](https://github.com/iamkun/dayjs/issues/2411)) ([95e9458](https://github.com/iamkun/dayjs/commit/95e9458b221fe35e59ee4a160a5db247313a68fb)) +* duration plugin - MILLISECONDS_A_MONTH const calculation ([#2362](https://github.com/iamkun/dayjs/issues/2362)) ([f0a0b54](https://github.com/iamkun/dayjs/commit/f0a0b546b074b3b511c2319a1ce83d412894b91f)) +* duration plugin getter get result 0 instead of undefined ([#2369](https://github.com/iamkun/dayjs/issues/2369)) ([061aa7e](https://github.com/iamkun/dayjs/commit/061aa7ed6c31696974665fc9b11a74d30841ebed)) +* fix isDayjs check logic ([#2383](https://github.com/iamkun/dayjs/issues/2383)) ([5f3f878](https://github.com/iamkun/dayjs/commit/5f3f8786c796cd432fe6bcb6966a810daea89203)) +* fix timezone plugin to get correct locale setting ([#2420](https://github.com/iamkun/dayjs/issues/2420)) ([4f45012](https://github.com/iamkun/dayjs/commit/4f4501256fa1bc72128aae1d841bbd782df86aed)) +* **locale:** add meridiem in `ar` locale ([#2418](https://github.com/iamkun/dayjs/issues/2418)) ([361be5c](https://github.com/iamkun/dayjs/commit/361be5c7c628614ee833d710acbe154a598b904d)) +* round durations to millisecond precision for ISO string ([#2367](https://github.com/iamkun/dayjs/issues/2367)) ([890a17a](https://github.com/iamkun/dayjs/commit/890a17a8d8ddd43c7c8b806e3afc7b27f3288d27)) +* sub-second precisions need to be rounded at the seconds field to avoid adding floats ([#2377](https://github.com/iamkun/dayjs/issues/2377)) ([a9d7d03](https://github.com/iamkun/dayjs/commit/a9d7d0398d22ebd4bfc3812ca0134a97606d54d9)) +* update $x logic to avoid plugin error ([#2429](https://github.com/iamkun/dayjs/issues/2429)) ([2254635](https://github.com/iamkun/dayjs/commit/22546357f30924fcff3b3ffa14fd04be21f97a5e)) +* Update Slovenian locale for relative time ([#2396](https://github.com/iamkun/dayjs/issues/2396)) ([5470a15](https://github.com/iamkun/dayjs/commit/5470a15e437fac803797363063b24f3ba3bd5299)) +* update uzbek language translation ([#2327](https://github.com/iamkun/dayjs/issues/2327)) ([0a91056](https://github.com/iamkun/dayjs/commit/0a910564d76dc7c128da8e0d85d8e11ebdb5660b)) + +## [1.11.9](https://github.com/iamkun/dayjs/compare/v1.11.8...v1.11.9) (2023-07-01) + + +### Bug Fixes + +* Add null to min and max plugin return type ([#2355](https://github.com/iamkun/dayjs/issues/2355)) ([62d9042](https://github.com/iamkun/dayjs/commit/62d9042eb84b78d78324694ccbeaad1679d37e68)) +* check if null passed to objectSupport parser ([#2175](https://github.com/iamkun/dayjs/issues/2175)) ([013968f](https://github.com/iamkun/dayjs/commit/013968f609c32e2269df69b4dd1feb2e8e1e035a)) +* dayjs.diff improve performance ([#2244](https://github.com/iamkun/dayjs/issues/2244)) ([33c80e1](https://github.com/iamkun/dayjs/commit/33c80e14cf14f70ceb4f54639e266cd70a3c3996)) +* dayjs(null) throws error, not return dayjs object as invalid date ([#2334](https://github.com/iamkun/dayjs/issues/2334)) ([c79e2f5](https://github.com/iamkun/dayjs/commit/c79e2f5d03eef5660b1f13385b69c0c9668d2f98)) +* objectSupport plugin causes an error when null is passed to dayjs function (closes [#2277](https://github.com/iamkun/dayjs/issues/2277)) ([#2342](https://github.com/iamkun/dayjs/issues/2342)) ([89bf31c](https://github.com/iamkun/dayjs/commit/89bf31ce0a36dcfc892029dc019d85d3654cf5fb)) +* Optimize format method ([#2313](https://github.com/iamkun/dayjs/issues/2313)) ([1fe1b1d](https://github.com/iamkun/dayjs/commit/1fe1b1d9a214d3b8c9f267b432801424a493f1c4)) +* update Duration plugin add/subtract take into account days in month ([#2337](https://github.com/iamkun/dayjs/issues/2337)) ([3b1060f](https://github.com/iamkun/dayjs/commit/3b1060f92183ab3a3c49289c2d87fbdd34c1eacc)) +* update MinMax plugin 1. ignore the 'null' in args 2. return the only one arg ([#2330](https://github.com/iamkun/dayjs/issues/2330)) ([3c2c6ee](https://github.com/iamkun/dayjs/commit/3c2c6ee4db00bbb43a7a3bb0b56bc0d0f03daddc)) + +## [1.11.8](https://github.com/iamkun/dayjs/compare/v1.11.7...v1.11.8) (2023-06-02) + + +### Bug Fixes + +* .format add padding to 'YYYY' ([#2231](https://github.com/iamkun/dayjs/issues/2231)) ([00c223b](https://github.com/iamkun/dayjs/commit/00c223b7e92970d07557133994fcb225a6d4c960)) +* Added .valueOf method to Duration class ([#2226](https://github.com/iamkun/dayjs/issues/2226)) ([9b4fcfd](https://github.com/iamkun/dayjs/commit/9b4fcfde35b39693894be1821b6c7222fac98657)) +* timezone type mark `date` parameter as optional ([#2222](https://github.com/iamkun/dayjs/issues/2222)) ([b87aa0e](https://github.com/iamkun/dayjs/commit/b87aa0ed9a748c478a66ef48230cd1d6350d7b8a)) +* type file first parameter date is optional in isSame(), isBefore(), isAfter() ([#2272](https://github.com/iamkun/dayjs/issues/2272)) ([4d56f3e](https://github.com/iamkun/dayjs/commit/4d56f3eb2b3770879d60f824590bf1b32f237d47)) + +## [1.11.7](https://github.com/iamkun/dayjs/compare/v1.11.6...v1.11.7) (2022-12-06) + + +### Bug Fixes + +* Add locale (zh-tw) meridiem ([#2149](https://github.com/iamkun/dayjs/issues/2149)) ([1e9ba76](https://github.com/iamkun/dayjs/commit/1e9ba761ff4e3f2759106dfe1aa9054d5826451c)) +* update fa locale ([#2151](https://github.com/iamkun/dayjs/issues/2151)) ([1c26732](https://github.com/iamkun/dayjs/commit/1c267321a1a01b4947e1482bac67d67ebc7c3dfa)) + +## [1.11.6](https://github.com/iamkun/dayjs/compare/v1.11.5...v1.11.6) (2022-10-21) + + +### Bug Fixes + +* add BigIntSupport plugin ([#2087](https://github.com/iamkun/dayjs/issues/2087)) ([f6dce48](https://github.com/iamkun/dayjs/commit/f6dce48a9e39677718b087867d9fd901d5078155)) +* Fix objectSupport collides with Duration plugin - issue [#2027](https://github.com/iamkun/dayjs/issues/2027) ([#2038](https://github.com/iamkun/dayjs/issues/2038)) ([c9370ea](https://github.com/iamkun/dayjs/commit/c9370ea96bf420439ee7eaa4146e8ed643160312)) + +## [1.11.5](https://github.com/iamkun/dayjs/compare/v1.11.4...v1.11.5) (2022-08-12) + + +### Bug Fixes + +* ordinal for nl not working ([#2011](https://github.com/iamkun/dayjs/issues/2011)) ([c93c85e](https://github.com/iamkun/dayjs/commit/c93c85eaa11564a1aae2d823480a417812c01bf4)) +* wrong ordinal for french locale ([#2010](https://github.com/iamkun/dayjs/issues/2010)) ([dd192a7](https://github.com/iamkun/dayjs/commit/dd192a72fc5d26ce56481e89b0c1ccf5f939be0c)) + +## [1.11.4](https://github.com/iamkun/dayjs/compare/v1.11.3...v1.11.4) (2022-07-19) + + +### Bug Fixes + +* correct past property in ku (kurdish) locale ([#1916](https://github.com/iamkun/dayjs/issues/1916)) ([74e82b9](https://github.com/iamkun/dayjs/commit/74e82b9da5ec8b90361fc27ac7c8b63faf354502)) +* fix French [fr] local ordinal ([#1932](https://github.com/iamkun/dayjs/issues/1932)) ([8f09834](https://github.com/iamkun/dayjs/commit/8f09834a88b8e7f8353c6e7473d4711596890a8c)) +* fix objectSupport plugin ConfigTypeMap type ([#1441](https://github.com/iamkun/dayjs/issues/1441)) ([#1990](https://github.com/iamkun/dayjs/issues/1990)) ([fd51fe4](https://github.com/iamkun/dayjs/commit/fd51fe4f7fa799d8c598343e71fa59299ec4cf93)) +* fix type error to add ordianl property in InstanceLocaleDataReturn and GlobalLocaleDataReturn types ([#1931](https://github.com/iamkun/dayjs/issues/1931)) ([526f0ae](https://github.com/iamkun/dayjs/commit/526f0ae549ffbeeb9ef1099ca23964791fc59743)) +* update locale ar-* meridiem function ([#1954](https://github.com/iamkun/dayjs/issues/1954)) ([3d31611](https://github.com/iamkun/dayjs/commit/3d316117f04362d31f4e8bd349620b8414ce5d0c)) +* zh-tw / zh-hk locale ordinal error ([#1976](https://github.com/iamkun/dayjs/issues/1976)) ([0a1bd08](https://github.com/iamkun/dayjs/commit/0a1bd08e736be7d4e378aaca280caa6543f8066d)) + ## [1.11.3](https://github.com/iamkun/dayjs/compare/v1.11.2...v1.11.3) (2022-06-06) diff --git a/README.md b/README.md index 728dadfbe..8423d7765 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -English | [简体中文](./docs/zh-cn/README.zh-CN.md) | [日本語](./docs/ja/README-ja.md) | [Português Brasileiro](./docs/pt-br/README-pt-br.md) | [한국어](./docs/ko/README-ko.md) | [Español (España)](./docs/es-es/README-es-es.md) | [Русский](./docs/ru/README-ru.md) | [Türkçe](./docs/tr/README-tr.md) +English | [简体中文](./docs/zh-cn/README.zh-CN.md) | [日本語](./docs/ja/README-ja.md) | [Português Brasileiro](./docs/pt-br/README-pt-br.md) | [한국어](./docs/ko/README-ko.md) | [Español (España)](./docs/es-es/README-es-es.md) | [Русский](./docs/ru/README-ru.md) | [Türkçe](./docs/tr/README-tr.md) | [සිංහල](./docs/si/README-si.md) | [עברית](./docs/he/README-he.md)

Day.js

+ alt="Day.js" />

Fast 2kB alternative to Moment.js with the same modern API

Gzip Size NPM Version - Build Status + Build Status Codecov + + + ## Sponsors -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. +Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor via Github](https://github.com/sponsors/iamkun/)] [[Become a sponsor via OpenCollective](https://opencollective.com/dayjs#sponsor)] + + + +         + + + +         + + + +                  - +          - +          - +          @@ -124,10 +143,11 @@ Please give us a 💖 star 💖 to support us. Thank you. And thank you to all our backers! 🙏 - - - - + + + + +
## License diff --git a/docs/es-es/README-es-es.md b/docs/es-es/README-es-es.md index ae190e846..d9b54c794 100644 --- a/docs/es-es/README-es-es.md +++ b/docs/es-es/README-es-es.md @@ -1,4 +1,4 @@ -Español (España) | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Русский](../ru/README-ru.md) +Español (España) | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Русский](../ru/README-ru.md) | [עברית](./docs/he/README-he.md)

Gzip Size NPM Version - Build Status + Build Status Codecov + + + ## Patrocinadores Apoya a este proyecto convirtiéndote en un patrocinador. Tu logo aparecerá aquí, enlazado a tu sitio web. [[Conviértete en un patrocinador](https://opencollective.com/dayjs#sponsor)] diff --git a/docs/he/README-he.md b/docs/he/README-he.md new file mode 100644 index 000000000..f410269ef --- /dev/null +++ b/docs/he/README-he.md @@ -0,0 +1,176 @@ +

+ +עברית | [English](../../README.md) | [简体中文](./docs/zh-cn/README.zh-CN.md) | [日本語](./docs/ja/README-ja.md) | [Português Brasileiro](./docs/pt-br/README-pt-br.md) | [한국어](./docs/ko/README-ko.md) | [Español (España)](./docs/es-es/README-es-es.md) | [Русский](./docs/ru/README-ru.md) | [Türkçe](./docs/tr/README-tr.md) | [සිංහල](./docs/si/README-si.md) + +

Day.js

+

אלטרנטיבה מהירה ל-Moment.js ששוקלת רק 2kB עם אותן יכולות מודרניות

+

+ Gzip Size + NPM Version + Build Status + Codecov + License +
+ + Sauce Test Status + +

+ +> Day.js היא ספרייה מינימלסטית לפענוח, אימות, מניפולציה והצגה של תאריכים ושעות לדפדפנים מודרנים עם תאימות גבוהה ל-API של Moment.js. אם השתמשתם ב-Moment.js, אתם כבר יודעים את Day.js + +
+ +```js +dayjs().startOf('month').add(1, 'day').set('year', 2018).format('YYYY-MM-DD HH:mm:ss'); +``` + +
+ +* 🕒 תבניות ו-API זהים ל-Moment.js +* 💪 אינו ניתן לשינוי +* 🔥 ניתן לשרשור +* 🌐 תמיכה ב-I18n +* 📦 ספרייה קטנטנה 2kb +* 👫 נתמכת בכל הדפדפנים + +--- + +## צעדים ראשונים + +### דוקומנטצייה +באתר [day.js.org](https://day.js.org/) ניתן למצוא פרטים נוספים, API, ותיעודים נוספים. + + +### התקנה + +```console +npm install dayjs --save +``` + +📚[מדריך התקנה](https://day.js.org/docs/en/installation/installation) + +### API +מאוד קל להשתמש ב-Day.js לפענוח, אימות, מניפולציה והצגה של תאריכים ושעות. + +
+ + +```javascript +dayjs('2018-08-08') // פענוח + +dayjs().format('{YYYY} MM-DDTHH:mm:ss SSS [Z] A') // הצגה + +dayjs().set('month', 3).month() // קבלה והגדרה + +dayjs().add(1, 'year') // מניפולציה + +dayjs().isBefore(dayjs()) // שאילתה +``` + +
+ +📚[תיעודי API](https://day.js.org/docs/en/parse/parse) + +### I18n +ל-Day.js יש תמיכה מצוינית בבינלאומיות. + +אבל אף אחד מהם לא יכלל בקובץ הסופי אלא אם כן יתבצע בהם שימוש. + +
+ + +```javascript +import 'dayjs/locale/es' // טעינה לפי הצורך + +dayjs.locale('es') // הגדרה לשימוש בספרדית באופן גלובלאלי + +dayjs('2018-05-05').locale('zh-cn').format() // הגדרה לשימוש בסינית פשוטה למופע ספיציפי בלבד +``` + +
+ + +📚[בינלאומיות](https://day.js.org/docs/en/i18n/i18n) + +### תוסף + +תוסף הוא מודל בלתי-תלוי הניתן להוספה ל-Day.js להרחבה או להוספה של פונקציות. + + +
+ + +```javascript +import advancedFormat from 'dayjs/plugin/advancedFormat' // טעינה לפי הצורך + +dayjs.extend(advancedFormat) // שימוש בתוסף + +dayjs().format('Q Do k kk X x') // כעת יותר אפשרויות זמינות +``` + +
+ +📚[רשימת תוספים](https://day.js.org/docs/en/plugin/plugin) + +### מגמת השימוש + + + + + +### ספונסרים +תמכו בפרויקט זה כדי להיות ספונסר. קבלו לוגו עם קישור לאתר שלכם שיופיע כאן. + +[[תמיכה דרך Github](https://github.com/sponsors/iamkun/)] [[תמיכה דרך OpenCollective](https://opencollective.com/dayjs#sponsor)] + + + + +         + + + +         + + + +         + + + +         + +         + +         + +         + + +## תורמים + +פרויקט זה קיים הודות לכל האנשים שתמכו בו. + +תנו לנו 💖 כוכב 💖 כדי לתמוך בנו. תודה רבה. + +ותודה רבה לכל התומכים שלנו! 🙏 + + + + + +
+ + +## רישיון + +Day.js מורשה לשימוש עם [רישיון MIT](./LICENSE). +
diff --git a/docs/ja/README-ja.md b/docs/ja/README-ja.md index b40ceeb4b..783e86801 100644 --- a/docs/ja/README-ja.md +++ b/docs/ja/README-ja.md @@ -1,4 +1,4 @@ -日本語 | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md) +日本語 | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md)| [עברית](../he/README-he.md)

Gzip Size NPM Version - Build Status + Build Status Codecov + + + ## ライセンス Day.js は [MIT License](../../LICENSE) のもとで利用を許諾します。 diff --git a/docs/ko/README-ko.md b/docs/ko/README-ko.md index 7d6228d28..3b1b985b5 100644 --- a/docs/ko/README-ko.md +++ b/docs/ko/README-ko.md @@ -1,4 +1,4 @@ -한국어 | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md) +한국어 | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md)| [עברית](./docs/he/README-he.md)

Gzip Size NPM Version - Build Status + Build Status Codecov

-> Day.js는 Moment.js와 호환되는 대부분의 API를 사용하며, 최신 브라우저에서 날짜와 시간에 대한 구문 분석, 유효성 검사, 조작, 출력하는 경량 JavaScript 라이브러리입니다. Moment.js를 사용하고 있다면, Day.js는 껌입니다. +> Day.js는 대부분의 API가 Moment.js와 호환되며 최신 브라우저에서 날짜와 시간에 대한 구문 분석, 유효성 검사, 조작, 출력을 간편하게 처리하는 경량 JavaScript 라이브러리 입니다. Moment.js를 사용해본 경험이 있다면, Day.js도 쉽게 사용하실 수 있습니다. ```js dayjs() @@ -46,7 +46,7 @@ dayjs() ### 문서 -더 많은 세부 사항과 API, 그리고 다른 문서를 [day.js.org](https://day.js.org/) 웹사이트에서 볼 수 있습니다. +더 많은 세부 사항과 API 및 다른 문서는 [day.js.org](https://day.js.org/) 웹사이트에서 확인하실 수 있습니다. ### 설치 @@ -58,7 +58,7 @@ npm install dayjs --save ### API -Day.js API를 사용해서 날짜와 시간에 대한 구문 분석, 유효성 검사, 조작, 출력을 쉽게 할 수 있습니다. +Day.js API를 사용하여 날짜와 시간의 구문 분석, 검증, 조작, 출력을 간편하게 처리할 수 있습니다. ```javascript dayjs('2018-08-08') // parse @@ -78,9 +78,9 @@ dayjs().isBefore(dayjs()) // query ### I18n -Day.js는 국제화에 대해 많은 지원을 합니다. +Day.js는 국제화에 대한 많은 지원을 제공하고 있습니다. -그러나 그것을 사용하지 않는다면, 그 누구도 당신의 빌드에 포함되지 않습니다. +하지만 이 기능을 사용하지 않는 경우, 빌드에 포함되지 않습니다. ```javascript import 'dayjs/locale/es' // load on demand @@ -96,7 +96,7 @@ dayjs('2018-05-05') ### Plugin -플러그인은 기능을 확장하거나 새로운 기능을 추가하기 위해 Day.js에 추가할 수 있는 독립적인 모듈입니다. +플러그인은 Day.js의 기능을 확장하거나 새로운 기능을 도입하기 위한 독립적인 모듈입니다. ```javascript import advancedFormat from 'dayjs/plugin/advancedFormat' // load on demand @@ -108,6 +108,12 @@ dayjs().format('Q Do k kk X x') // more available formats 📚[플러그인 목록](https://day.js.org/docs/en/plugin/plugin) +### 사용 트렌드 + + + + + ## License Day.js는 [MIT License](./LICENSE)를 사용합니다. diff --git a/docs/pt-br/README-pt-br.md b/docs/pt-br/README-pt-br.md index 4923fa58d..31d0bdbc4 100644 --- a/docs/pt-br/README-pt-br.md +++ b/docs/pt-br/README-pt-br.md @@ -1,4 +1,4 @@ -Português Brasileiro | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md) +Português Brasileiro | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md)| [עברית](./docs/he/README-he.md)

Gzip Size NPM Version - Build Status + Build Status Codecov + + + ## Patrocinadores Ajude este projeto se tornando um patrocinador. O seu logo será exibido aqui, com um link para o seu site. [[Tornar-se um Patrocinador](https://opencollective.com/dayjs#sponsor)]. diff --git a/docs/ru/README-ru.md b/docs/ru/README-ru.md index c8f9b83ca..065af14ba 100644 --- a/docs/ru/README-ru.md +++ b/docs/ru/README-ru.md @@ -1,4 +1,4 @@ -Русский | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) +Русский | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md)| [עברית](./docs/he/README-he.md)

Gzip Size NPM Version - Build Status + Build Status Codecov + + + ## Спонсоры Поддержите этот проект, став спонсором. Ваш логотип будет показан здесь с ссылкой на ваш веб-сайт. [[Стать спонсором](https://opencollective.com/dayjs#sponsor)] diff --git a/docs/si/README-si.md b/docs/si/README-si.md new file mode 100644 index 000000000..e5f7fb92b --- /dev/null +++ b/docs/si/README-si.md @@ -0,0 +1,141 @@ +සිංහල | [English](../../README.md) | [简体中文](./docs/zh-cn/README.zh-CN.md) | [日本語](./docs/ja/README-ja.md) | [Português Brasileiro](./docs/pt-br/README-pt-br.md) | [한국어](./docs/ko/README-ko.md) | [Español (España)](./docs/es-es/README-es-es.md) | [Русский](./docs/ru/README-ru.md) | [Türkçe](./docs/tr/README-tr.md)| [עברית](./docs/he/README-he.md) + +

Day.js

+

නවීන යෙ.ක්‍ර.මු. සමඟින් Moment.js සඳහා කි.බ. 2 ක වේගවත් විකල්පයකි

+

+ Gzip Size + NPM Version + Build Status + Codecov + License +
+ + Sauce Test Status + +

+ +> Day.js යනු බොහෝ සෙයින් Moment.js-ගැළපෙන යෙ.ක්‍ර.මු. සහිත නවීන අතිරික්සු සඳහා දින සහ වේලාවන් ප්‍රදර්ශනයට, හැසිරවීමට, වලංගු කිරීමට සහ විග්‍රහ කිරීමට ඉතා කුඩා ජාවාස්ක්‍රිප්ට් එකතුවකි. Moment.js භාවිතා කරන්නේ නම්, Day.js භාවිතා කරන අයුරු ඔබ දැනටමත් දන්නවා. + +```js +dayjs().startOf('month').add(1, 'day').set('year', 2018).format('YYYY-MM-DD HH:mm:ss'); +``` + +* 🕒 හුරුපුරුදු Moment.js යෙ.ක්‍ර.මු. හා රටා +* 💪 නිත්‍යයි +* 🔥 ඈඳීමට හැකිය +* 🌐 I18n සහාය +* 📦 කි.බ. 2 ක කුඩා එකතුව +* 👫 සියළු අතිරික්සු සඳහා සහාය + +--- + +## පටන් ගැනීම + +### ප්‍රලේඛනය + +[day.js.org](https://day.js.org/) වියමන අඩවියෙහි යෙ.ක්‍ර.මු. සහ වෙනත් ප්‍රලේඛනවල වැඩි විස්තර සොයා ගැනීමට හැකිය. + +### ස්ථාපනය + +```console +npm install dayjs --save +``` + +📚[ ස්ථාපන මාර්ගෝපදේශය](https://day.js.org/docs/en/installation/installation) + +### යෙ.ක්‍ර.මු. + +දින සහ වේලාවන් ප්‍රදර්ශනයට, හැසිරවීමට, වලංගු කිරීමට සහ විග්‍රහ කිරීමට Day.js යෙ.ක්‍ර.මු. භාවිතා කිරීම පහසුය. + +```javascript +dayjs('2018-08-08') // parse + +dayjs().format('{YYYY} MM-DDTHH:mm:ss SSS [Z] A') // display + +dayjs().set('month', 3).month() // get & set + +dayjs().add(1, 'year') // manipulate + +dayjs().isBefore(dayjs()) // query +``` + +📚[ යෙ.ක්‍ර.මු. යොමුව](https://day.js.org/docs/en/parse/parse) + +### I18n + +දේශීයකරණය සඳහා Day.js සුවිශේෂී ලෙස සහය දක්වයි. + +නමුත් භාවිතා කරන්නේ නම් මිස ඒවා කිසිවක් ඔබගේ තැනීමට ඇතුළත් නොවේ. + +```javascript +import 'dayjs/locale/es' // load on demand + +dayjs.locale('es') // use Spanish locale globally + +dayjs('2018-05-05').locale('zh-cn').format() // use Chinese Simplified locale in a specific instance +``` +📚[ දේශීයකරණය](https://day.js.org/docs/en/i18n/i18n) + +### දිගුව + +දිගුවක් යනු ක්‍රියාකාරිත්වය විස්තීරණයට හෝ නව විශේෂාංග අඩංගු කිරීමට Day.js වෙත එකතු කළ හැකි ස්වාධීන ඒකකයකි. + +```javascript +import advancedFormat from 'dayjs/plugin/advancedFormat' // load on demand + +dayjs.extend(advancedFormat) // use plugin + +dayjs().format('Q Do k kk X x') // more available formats +``` + +📚[ දිගු ලේඛනය](https://day.js.org/docs/en/plugin/plugin) + +### භාවිත ප්‍රමාණයේ ප්‍රසූතිය + + + + + +## අනුග්‍රාහකයින් + +අනුග්‍රහය දැක්වීමෙන් මෙම ව්‍යාපෘතියට සහාය වන්න. ඔබගේ අඩවියේ සබැඳියක් සමඟ ඔබගේ ලාංඡනය මෙහි පෙන්වනු ඇත. + +[[ගිට්හබ් හරහා අනුග්‍රාහකයෙකු වන්න](https://github.com/sponsors/iamkun/)] [[ඕපන්කලෙක්ටිව් හරහා අනුග්‍රාහකයෙකු වන්න](https://opencollective.com/dayjs#sponsor)] + + + + +         + +         + +         + +         + + +## දායකයින් + +මෙම ව්‍යාපෘතිය පවතිනුයේ දායක වූ සියළුම දෙනාට ස්තූති වන්නටය. + +අපට සහාය වීමට 💖 තරුවක් 💖 ලබා දෙන්න. ඔබට තුති. + +ඒ වගේම අපගේ මූල්‍යදායකයින් සැමට ස්තුතියි! 🙏 + + + + + + + +## බලපත්‍රය + +[MIT බලපත්‍රයක්](./LICENSE) යටතේ Day.js නිකුත් කර ඇත. diff --git a/docs/tr/README-tr.md b/docs/tr/README-tr.md index c5d88404b..2b1a63549 100644 --- a/docs/tr/README-tr.md +++ b/docs/tr/README-tr.md @@ -1,4 +1,4 @@ -Türkçe | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md) +Türkçe | [English](../../README.md) | [简体中文](../zh-cn/README.zh-CN.md) | [日本語](../ja/README-ja.md) | [Português Brasileiro](../pt-br/README-pt-br.md) | [한국어](../ko/README-ko.md) | [Español (España)](../es-es/README-es-es.md) | [Русский](../ru/README-ru.md)| [עברית](./docs/he/README-he.md)

Gzip Size NPM Version - Build Status + Build Status Codecov + + + ## Sponsorlar Sponsor olarak bu projeye destek olun. Logonuz, web sayfanızın linki ile birlikte burada görünür. [[Sponsor Ol](https://opencollective.com/dayjs#sponsor)] @@ -133,4 +139,4 @@ Ve tüm destekçilerimize teşekkür ederiz! 🙏 ## Lisans -Day.js, bir [MIT Lisansı](../../LICENSE) altında lisanslanmıştır. \ No newline at end of file +Day.js, bir [MIT Lisansı](../../LICENSE) altında lisanslanmıştır. diff --git a/docs/zh-cn/README.zh-CN.md b/docs/zh-cn/README.zh-CN.md index b543a80f1..d7bb1ecbc 100644 --- a/docs/zh-cn/README.zh-CN.md +++ b/docs/zh-cn/README.zh-CN.md @@ -11,8 +11,8 @@ alt="Gzip Size"> NPM Version - Build Status + Build Status Codecov + + + ## 开源协议 Day.js 遵循 [MIT 开源协议](../../LICENSE). diff --git a/package.json b/package.json index 44b293c48..c76e01780 100644 --- a/package.json +++ b/package.json @@ -36,21 +36,6 @@ "src/**/*" ] }, - "release": { - "prepare": [ - { - "path": "@semantic-release/changelog" - }, - [ - "@semantic-release/git", - { - "assets": [ - "CHANGELOG.md" - ] - } - ] - ] - }, "keywords": [ "dayjs", "date", diff --git a/src/index.js b/src/index.js index 19c409078..061ade178 100644 --- a/src/index.js +++ b/src/index.js @@ -6,7 +6,10 @@ let L = 'en' // global locale const Ls = {} // global loaded locale Ls[L] = en -const isDayjs = d => d instanceof Dayjs // eslint-disable-line no-use-before-define +const IS_DAYJS = '$isDayjsObject' + +// eslint-disable-next-line no-use-before-define +const isDayjs = d => d instanceof Dayjs || !!(d && d[IS_DAYJS]) const parseLocale = (preset, object, isLocal) => { let l @@ -72,7 +75,7 @@ const parseDate = (cfg) => { || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms)) } return new Date(d[1], m, d[3] - || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms) + || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms) } } @@ -83,11 +86,12 @@ class Dayjs { constructor(cfg) { this.$L = parseLocale(cfg.locale, null, true) this.parse(cfg) // for plugin + this.$x = this.$x || cfg.x || {} + this[IS_DAYJS] = true } parse(cfg) { this.$d = parseDate(cfg) - this.$x = cfg.x || {} this.init() } @@ -278,34 +282,63 @@ class Dayjs { return isLowercase ? m.toLowerCase() : m }) - const matches = { - YY: String(this.$y).slice(-2), - YYYY: this.$y, - M: $M + 1, - MM: Utils.s($M + 1, 2, '0'), - MMM: getShort(locale.monthsShort, $M, months, 3), - MMMM: getShort(months, $M), - D: this.$D, - DD: Utils.s(this.$D, 2, '0'), - d: String(this.$W), - dd: getShort(locale.weekdaysMin, this.$W, weekdays, 2), - ddd: getShort(locale.weekdaysShort, this.$W, weekdays, 3), - dddd: weekdays[this.$W], - H: String($H), - HH: Utils.s($H, 2, '0'), - h: get$H(1), - hh: get$H(2), - a: meridiemFunc($H, $m, true), - A: meridiemFunc($H, $m, false), - m: String($m), - mm: Utils.s($m, 2, '0'), - s: String(this.$s), - ss: Utils.s(this.$s, 2, '0'), - SSS: Utils.s(this.$ms, 3, '0'), - Z: zoneStr // 'ZZ' logic below + const matches = (match) => { + switch (match) { + case 'YY': + return String(this.$y).slice(-2) + case 'YYYY': + return Utils.s(this.$y, 4, '0') + case 'M': + return $M + 1 + case 'MM': + return Utils.s($M + 1, 2, '0') + case 'MMM': + return getShort(locale.monthsShort, $M, months, 3) + case 'MMMM': + return getShort(months, $M) + case 'D': + return this.$D + case 'DD': + return Utils.s(this.$D, 2, '0') + case 'd': + return String(this.$W) + case 'dd': + return getShort(locale.weekdaysMin, this.$W, weekdays, 2) + case 'ddd': + return getShort(locale.weekdaysShort, this.$W, weekdays, 3) + case 'dddd': + return weekdays[this.$W] + case 'H': + return String($H) + case 'HH': + return Utils.s($H, 2, '0') + case 'h': + return get$H(1) + case 'hh': + return get$H(2) + case 'a': + return meridiemFunc($H, $m, true) + case 'A': + return meridiemFunc($H, $m, false) + case 'm': + return String($m) + case 'mm': + return Utils.s($m, 2, '0') + case 's': + return String(this.$s) + case 'ss': + return Utils.s(this.$s, 2, '0') + case 'SSS': + return Utils.s(this.$ms, 3, '0') + case 'Z': + return zoneStr // 'ZZ' logic below + default: + break + } + return null } - return str.replace(C.REGEX_FORMAT, (match, $1) => $1 || matches[match] || zoneStr.replace(':', '')) // 'ZZ' + return str.replace(C.REGEX_FORMAT, (match, $1) => $1 || matches(match) || zoneStr.replace(':', '')) // 'ZZ' } utcOffset() { @@ -319,18 +352,38 @@ class Dayjs { const that = dayjs(input) const zoneDelta = (that.utcOffset() - this.utcOffset()) * C.MILLISECONDS_A_MINUTE const diff = this - that - let result = Utils.m(this, that) - - result = { - [C.Y]: result / 12, - [C.M]: result, - [C.Q]: result / 3, - [C.W]: (diff - zoneDelta) / C.MILLISECONDS_A_WEEK, - [C.D]: (diff - zoneDelta) / C.MILLISECONDS_A_DAY, - [C.H]: diff / C.MILLISECONDS_A_HOUR, - [C.MIN]: diff / C.MILLISECONDS_A_MINUTE, - [C.S]: diff / C.MILLISECONDS_A_SECOND - }[unit] || diff // milliseconds + const getMonth = () => Utils.m(this, that) + + let result + switch (unit) { + case C.Y: + result = getMonth() / 12 + break + case C.M: + result = getMonth() + break + case C.Q: + result = getMonth() / 3 + break + case C.W: + result = (diff - zoneDelta) / C.MILLISECONDS_A_WEEK + break + case C.D: + result = (diff - zoneDelta) / C.MILLISECONDS_A_DAY + break + case C.H: + result = diff / C.MILLISECONDS_A_HOUR + break + case C.MIN: + result = diff / C.MILLISECONDS_A_MINUTE + break + case C.S: + result = diff / C.MILLISECONDS_A_SECOND + break + default: + result = diff // milliseconds + break + } return float ? result : Utils.a(result) } diff --git a/src/locale/ar-dz.js b/src/locale/ar-dz.js index fdc5e0b86..cd076f7d7 100644 --- a/src/locale/ar-dz.js +++ b/src/locale/ar-dz.js @@ -17,7 +17,7 @@ const locale = { LLL: 'D MMMM YYYY HH:mm', LLLL: 'dddd D MMMM YYYY HH:mm' }, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'في %s', past: 'منذ %s', diff --git a/src/locale/ar-iq.js b/src/locale/ar-iq.js index 1040db80d..7878f6481 100644 --- a/src/locale/ar-iq.js +++ b/src/locale/ar-iq.js @@ -18,7 +18,7 @@ const locale = { LLL: 'D MMMM YYYY HH:mm', LLLL: 'dddd D MMMM YYYY HH:mm' }, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'في %s', past: 'منذ %s', diff --git a/src/locale/ar-kw.js b/src/locale/ar-kw.js index 23ad4be6c..465ff9936 100644 --- a/src/locale/ar-kw.js +++ b/src/locale/ar-kw.js @@ -17,7 +17,7 @@ const locale = { LLL: 'D MMMM YYYY HH:mm', LLLL: 'dddd D MMMM YYYY HH:mm' }, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'في %s', past: 'منذ %s', diff --git a/src/locale/ar-ly.js b/src/locale/ar-ly.js index 6db397056..316627099 100644 --- a/src/locale/ar-ly.js +++ b/src/locale/ar-ly.js @@ -10,7 +10,7 @@ const locale = { monthsShort: 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), ordinal: n => n, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), formats: { LT: 'HH:mm', LTS: 'HH:mm:ss', diff --git a/src/locale/ar-ma.js b/src/locale/ar-ma.js index 802b71684..5b1e70aed 100644 --- a/src/locale/ar-ma.js +++ b/src/locale/ar-ma.js @@ -18,7 +18,7 @@ const locale = { LLL: 'D MMMM YYYY HH:mm', LLLL: 'dddd D MMMM YYYY HH:mm' }, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'في %s', past: 'منذ %s', diff --git a/src/locale/ar-sa.js b/src/locale/ar-sa.js index 9f908ade1..f543bac22 100644 --- a/src/locale/ar-sa.js +++ b/src/locale/ar-sa.js @@ -17,7 +17,7 @@ const locale = { LLL: 'D MMMM YYYY HH:mm', LLLL: 'dddd D MMMM YYYY HH:mm' }, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'في %s', past: 'منذ %s', diff --git a/src/locale/ar-tn.js b/src/locale/ar-tn.js index 54c4e3e2d..c44cf66c1 100644 --- a/src/locale/ar-tn.js +++ b/src/locale/ar-tn.js @@ -18,7 +18,7 @@ const locale = { LLL: 'D MMMM YYYY HH:mm', LLLL: 'dddd D MMMM YYYY HH:mm' }, - meridiem: hour => (hour > 12 ? 'ص' : 'م'), + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'في %s', past: 'منذ %s', diff --git a/src/locale/ar.js b/src/locale/ar.js index a7025c442..f418379c8 100644 --- a/src/locale/ar.js +++ b/src/locale/ar.js @@ -2,6 +2,7 @@ import dayjs from 'dayjs' const months = 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_') + const symbolMap = { 1: '١', 2: '٢', @@ -36,6 +37,7 @@ const locale = { months, monthsShort: months, weekStart: 6, + meridiem: hour => (hour > 12 ? 'م' : 'ص'), relativeTime: { future: 'بعد %s', past: 'منذ %s', diff --git a/src/locale/en.js b/src/locale/en.js index 71c2f226e..2913d5772 100644 --- a/src/locale/en.js +++ b/src/locale/en.js @@ -3,5 +3,10 @@ export default { name: 'en', weekdays: 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_') + months: 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), + ordinal: (n) => { + const s = ['th', 'st', 'nd', 'rd'] + const v = n % 100 + return `[${n}${(s[(v - 20) % 10] || s[v] || s[0])}]` + } } diff --git a/src/locale/fr.js b/src/locale/fr.js index e913b4aa7..be06169f6 100644 --- a/src/locale/fr.js +++ b/src/locale/fr.js @@ -34,7 +34,7 @@ const locale = { yy: '%d ans' }, ordinal: (n) => { - const o = n === 1 ? 'er' : 'e' + const o = n === 1 ? 'er' : '' return `${n}${o}` } } diff --git a/src/locale/ko.js b/src/locale/ko.js index 8a8e8ea9b..7053e83f3 100644 --- a/src/locale/ko.js +++ b/src/locale/ko.js @@ -8,7 +8,7 @@ const locale = { weekdaysMin: '일_월_화_수_목_금_토'.split('_'), months: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), monthsShort: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - ordinal: n => n, + ordinal: n => `${n}일`, formats: { LT: 'A h:mm', LTS: 'A h:mm:ss', diff --git a/src/locale/ku.js b/src/locale/ku.js index 1d7a449d8..c87c5d88c 100644 --- a/src/locale/ku.js +++ b/src/locale/ku.js @@ -72,7 +72,7 @@ const locale = { meridiem: hour => (hour < 12 ? 'پ.ن' : 'د.ن'), relativeTime: { future: 'لە %s', - past: '%s', + past: 'لەمەوپێش %s', s: 'چەند چرکەیەک', m: 'یەک خولەک', mm: '%d خولەک', diff --git a/src/locale/nl.js b/src/locale/nl.js index 6d9ff7b04..49dc6bbcc 100644 --- a/src/locale/nl.js +++ b/src/locale/nl.js @@ -8,7 +8,7 @@ const locale = { weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'), months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), monthsShort: 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'), - ordinal: n => `${n}${n === 1 || n === 8 || n >= 20 ? 'ste' : 'de'}`, + ordinal: n => `[${n}${n === 1 || n === 8 || n >= 20 ? 'ste' : 'de'}]`, weekStart: 1, yearStart: 4, formats: { diff --git a/src/locale/sl.js b/src/locale/sl.js index f09e3bfce..1e0e4f885 100644 --- a/src/locale/sl.js +++ b/src/locale/sl.js @@ -1,6 +1,71 @@ // Slovenian [sl] import dayjs from 'dayjs' +function dual(n) { + return (n % 100) == 2 // eslint-disable-line +} + +function threeFour(n) { + return (n % 100) == 3 || (n % 100) == 4 // eslint-disable-line +} + +/* eslint-disable */ +function translate(number, withoutSuffix, key, isFuture) { + const result = `${number} ` + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'nekaj sekund' : 'nekaj sekundami' + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'ena minuta' : 'eno minuto' + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (dual(number)) { + return result + ((withoutSuffix || isFuture) ? 'minuti' : 'minutama') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'minute' : 'minutami') + } + return result + ((withoutSuffix || isFuture) ? 'minut' : 'minutami') + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'ena ura' : (isFuture ? 'eno uro' : 'eno uro') + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (dual(number)) { + return result + ((withoutSuffix || isFuture) ? 'uri' : 'urama') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'ure' : 'urami') + } + return result + ((withoutSuffix || isFuture) ? 'ur' : 'urami') + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'en dan' : 'enim dnem' + case 'dd': // 9 days / in 9 days / 9 days ago + if (dual(number)) { + return result + ((withoutSuffix || isFuture) ? 'dneva' : 'dnevoma') + } + return result + ((withoutSuffix || isFuture) ? 'dni' : 'dnevi') + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'en mesec' : 'enim mesecem' + case 'MM': // 9 months / in 9 months / 9 months ago + if (dual(number)) { // 2 minutes / in 2 minutes + return result + ((withoutSuffix || isFuture) ? 'meseca' : 'mesecema') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'mesece' : 'meseci') + } + return result + ((withoutSuffix || isFuture) ? 'mesecev' : 'meseci') + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'eno leto' : 'enim letom' + case 'yy': // 9 years / in 9 years / 9 years ago + if (dual(number)) { // 2 minutes / in 2 minutes + return result + ((withoutSuffix || isFuture) ? 'leti' : 'letoma') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'leta' : 'leti') + } + return result + ((withoutSuffix || isFuture) ? 'let' : 'leti') + } +} + +/* eslint-enable */ const locale = { name: 'sl', weekdays: 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), @@ -16,26 +81,26 @@ const locale = { L: 'DD.MM.YYYY', LL: 'D. MMMM YYYY', LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' + LLLL: 'dddd, D. MMMM YYYY H:mm', + l: 'D. M. YYYY' }, relativeTime: { future: 'čez %s', past: 'pred %s', - s: 'nekaj sekund', - m: 'minuta', - mm: '%d minut', - h: 'ura', - hh: '%d ur', - d: 'dan', - dd: '%d dni', - M: 'mesec', - MM: '%d mesecev', - y: 'leto', - yy: '%d let' + s: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate } } dayjs.locale(locale, null, true) export default locale - diff --git a/src/locale/uz-latn.js b/src/locale/uz-latn.js index 220d5d44c..7d6021921 100644 --- a/src/locale/uz-latn.js +++ b/src/locale/uz-latn.js @@ -20,7 +20,7 @@ const locale = { }, relativeTime: { future: 'Yaqin %s ichida', - past: 'Bir necha %s oldin', + past: '%s oldin', s: 'soniya', m: 'bir daqiqa', mm: '%d daqiqa', diff --git a/src/locale/uz.js b/src/locale/uz.js index 23f4042eb..e705f68bd 100644 --- a/src/locale/uz.js +++ b/src/locale/uz.js @@ -20,7 +20,7 @@ const locale = { }, relativeTime: { future: 'Якин %s ичида', - past: 'Бир неча %s олдин', + past: '%s олдин', s: 'фурсат', m: 'бир дакика', mm: '%d дакика', diff --git a/src/locale/zh-hk.js b/src/locale/zh-hk.js index 3c38d0756..193f2e2d8 100644 --- a/src/locale/zh-hk.js +++ b/src/locale/zh-hk.js @@ -8,14 +8,25 @@ const locale = { weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), weekdaysShort: '週日_週一_週二_週三_週四_週五_週六'.split('_'), weekdaysMin: '日_一_二_三_四_五_六'.split('_'), - ordinal: n => `${n}日`, + ordinal: (number, period) => { + switch (period) { + case 'W': + return `${number}週` + default: + return `${number}日` + } + }, formats: { LT: 'HH:mm', LTS: 'HH:mm:ss', L: 'YYYY/MM/DD', LL: 'YYYY年M月D日', LLL: 'YYYY年M月D日 HH:mm', - LLLL: 'YYYY年M月D日dddd HH:mm' + LLLL: 'YYYY年M月D日dddd HH:mm', + l: 'YYYY/M/D', + ll: 'YYYY年M月D日', + lll: 'YYYY年M月D日 HH:mm', + llll: 'YYYY年M月D日dddd HH:mm' }, relativeTime: { future: '%s內', @@ -31,6 +42,21 @@ const locale = { MM: '%d 個月', y: '一年', yy: '%d 年' + }, + meridiem: (hour, minute) => { + const hm = (hour * 100) + minute + if (hm < 600) { + return '凌晨' + } else if (hm < 900) { + return '早上' + } else if (hm < 1100) { + return '上午' + } else if (hm < 1300) { + return '中午' + } else if (hm < 1800) { + return '下午' + } + return '晚上' } } diff --git a/src/locale/zh-tw.js b/src/locale/zh-tw.js index b7880674d..709f70cff 100644 --- a/src/locale/zh-tw.js +++ b/src/locale/zh-tw.js @@ -8,7 +8,14 @@ const locale = { weekdaysMin: '日_一_二_三_四_五_六'.split('_'), months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - ordinal: n => `${n}日`, + ordinal: (number, period) => { + switch (period) { + case 'W': + return `${number}週` + default: + return `${number}日` + } + }, formats: { LT: 'HH:mm', LTS: 'HH:mm:ss', @@ -35,10 +42,24 @@ const locale = { MM: '%d 個月', y: '1 年', yy: '%d 年' + }, + meridiem: (hour, minute) => { + const hm = (hour * 100) + minute + if (hm < 600) { + return '凌晨' + } else if (hm < 900) { + return '早上' + } else if (hm < 1100) { + return '上午' + } else if (hm < 1300) { + return '中午' + } else if (hm < 1800) { + return '下午' + } + return '晚上' } } dayjs.locale(locale, null, true) export default locale - diff --git a/src/plugin/advancedFormat/index.js b/src/plugin/advancedFormat/index.js index a78296f7a..7794af987 100644 --- a/src/plugin/advancedFormat/index.js +++ b/src/plugin/advancedFormat/index.js @@ -1,14 +1,8 @@ import { FORMAT_DEFAULT } from '../../constant' -export default (o, c, d) => { // locale needed later +export default (o, c) => { // locale needed later const proto = c.prototype const oldFormat = proto.format - d.en.ordinal = (number) => { - const s = ['th', 'st', 'nd', 'rd'] - const v = number % 100 - return `[${number}${(s[(v - 20) % 10] || s[v] || s[0])}]` - } - // extend en locale here proto.format = function (formatStr) { const locale = this.$locale() diff --git a/src/plugin/bigIntSupport/index.js b/src/plugin/bigIntSupport/index.js new file mode 100644 index 000000000..a90bae1fe --- /dev/null +++ b/src/plugin/bigIntSupport/index.js @@ -0,0 +1,25 @@ +// eslint-disable-next-line valid-typeof +const isBigInt = num => typeof num === 'bigint' +export default (o, c, dayjs) => { + const proto = c.prototype + const parseDate = (cfg) => { + const { date } = cfg + if (isBigInt(date)) { + return Number(date) + } + return date + } + + const oldParse = proto.parse + proto.parse = function (cfg) { + cfg.date = parseDate.bind(this)(cfg) + oldParse.bind(this)(cfg) + } + + + const oldUnix = dayjs.unix + dayjs.unix = function (timestamp) { + const ts = isBigInt(timestamp) ? Number(timestamp) : timestamp + return oldUnix(ts) + } +} diff --git a/src/plugin/duration/index.js b/src/plugin/duration/index.js index 10ebb4ca2..e2060c344 100644 --- a/src/plugin/duration/index.js +++ b/src/plugin/duration/index.js @@ -8,7 +8,7 @@ import { } from '../../constant' const MILLISECONDS_A_YEAR = MILLISECONDS_A_DAY * 365 -const MILLISECONDS_A_MONTH = MILLISECONDS_A_DAY * 30 +const MILLISECONDS_A_MONTH = MILLISECONDS_A_YEAR / 12 const durationRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/ @@ -140,6 +140,7 @@ class Duration { let seconds = this.$d.seconds || 0 if (this.$d.milliseconds) { seconds += this.$d.milliseconds / 1000 + seconds = Math.round(seconds * 1000) / 1000 } const S = getNumberUnitFormat(seconds, 'S') @@ -198,7 +199,7 @@ class Duration { } else { base = this.$d[pUnit] } - return base === 0 ? 0 : base // a === 0 will be true on both 0 and -0 + return base || 0 // a === 0 will be true on both 0 and -0 } add(input, unit, isSubtract) { @@ -235,6 +236,10 @@ class Duration { .fromNow(!withSuffix) } + valueOf() { + return this.asMilliseconds() + } + milliseconds() { return this.get('milliseconds') } asMilliseconds() { return this.as('milliseconds') } seconds() { return this.get('seconds') } @@ -253,6 +258,15 @@ class Duration { asYears() { return this.as('years') } } +const manipulateDuration = (date, duration, k) => + date.add(duration.years() * k, 'y') + .add(duration.months() * k, 'M') + .add(duration.days() * k, 'd') + .add(duration.hours() * k, 'h') + .add(duration.minutes() * k, 'm') + .add(duration.seconds() * k, 's') + .add(duration.milliseconds() * k, 'ms') + export default (option, Dayjs, dayjs) => { $d = dayjs $u = dayjs().$utils() @@ -264,12 +278,20 @@ export default (option, Dayjs, dayjs) => { const oldAdd = Dayjs.prototype.add const oldSubtract = Dayjs.prototype.subtract + Dayjs.prototype.add = function (value, unit) { - if (isDuration(value)) value = value.asMilliseconds() + if (isDuration(value)) { + return manipulateDuration(this, value, 1) + } + return oldAdd.bind(this)(value, unit) } + Dayjs.prototype.subtract = function (value, unit) { - if (isDuration(value)) value = value.asMilliseconds() + if (isDuration(value)) { + return manipulateDuration(this, value, -1) + } + return oldSubtract.bind(this)(value, unit) } } diff --git a/src/plugin/minMax/index.js b/src/plugin/minMax/index.js index f515c60d9..8b3e2d3fe 100644 --- a/src/plugin/minMax/index.js +++ b/src/plugin/minMax/index.js @@ -1,12 +1,18 @@ export default (o, c, d) => { const sortBy = (method, dates) => { - if (!dates || !dates.length || !dates[0] || (dates.length === 1 && !dates[0].length)) { + if ( + !dates || + !dates.length || + (dates.length === 1 && !dates[0]) || + (dates.length === 1 && Array.isArray(dates[0]) && !dates[0].length) + ) { return null } if (dates.length === 1 && dates[0].length > 0) { [dates] = dates } - let result + dates = dates.filter(date => date) + let result; [result] = dates for (let i = 1; i < dates.length; i += 1) { if (!dates[i].isValid() || dates[i][method](result)) { diff --git a/src/plugin/objectSupport/index.js b/src/plugin/objectSupport/index.js index 4344dc402..bd32358e9 100644 --- a/src/plugin/objectSupport/index.js +++ b/src/plugin/objectSupport/index.js @@ -1,6 +1,7 @@ export default (o, c, dayjs) => { const proto = c.prototype - const isObject = obj => !(obj instanceof Date) && !(obj instanceof Array) && obj instanceof Object + const isObject = obj => obj !== null && !(obj instanceof Date) && !(obj instanceof Array) + && !proto.$utils().u(obj) && (obj.constructor.name === 'Object') const prettyUnit = (u) => { const unit = proto.$utils().p(u) return unit === 'date' ? 'day' : unit @@ -39,29 +40,36 @@ export default (o, c, dayjs) => { const oldSet = proto.set const oldAdd = proto.add + const oldSubtract = proto.subtract const callObject = function (call, argument, string, offset = 1) { - if (argument instanceof Object) { - const keys = Object.keys(argument) - let chain = this - keys.forEach((key) => { - chain = call.bind(chain)(argument[key] * offset, key) - }) - return chain - } - return call.bind(this)(argument * offset, string) + const keys = Object.keys(argument) + let chain = this + keys.forEach((key) => { + chain = call.bind(chain)(argument[key] * offset, key) + }) + return chain } - proto.set = function (string, int) { - int = int === undefined ? string : int - return callObject.bind(this)(function (i, s) { - return oldSet.bind(this)(s, i) - }, int, string) + proto.set = function (unit, value) { + value = value === undefined ? unit : value + if (unit.constructor.name === 'Object') { + return callObject.bind(this)(function (i, s) { + return oldSet.bind(this)(s, i) + }, value, unit) + } + return oldSet.bind(this)(unit, value) } - proto.add = function (number, string) { - return callObject.bind(this)(oldAdd, number, string) + proto.add = function (value, unit) { + if (value.constructor.name === 'Object') { + return callObject.bind(this)(oldAdd, value, unit) + } + return oldAdd.bind(this)(value, unit) } - proto.subtract = function (number, string) { - return callObject.bind(this)(oldAdd, number, string, -1) + proto.subtract = function (value, unit) { + if (value.constructor.name === 'Object') { + return callObject.bind(this)(oldAdd, value, unit, -1) + } + return oldSubtract.bind(this)(value, unit) } } diff --git a/src/plugin/timezone/index.js b/src/plugin/timezone/index.js index c8f8a4675..832fb4a73 100644 --- a/src/plugin/timezone/index.js +++ b/src/plugin/timezone/index.js @@ -97,7 +97,7 @@ export default (o, c, d) => { const date = this.toDate() const target = date.toLocaleString('en-US', { timeZone: timezone }) const diff = Math.round((date - new Date(target)) / 1000 / 60) - let ins = d(target).$set(MS, this.$ms) + let ins = d(target, { locale: this.$L }).$set(MS, this.$ms) .utcOffset((-Math.round(date.getTimezoneOffset() / 15) * 15) - diff, true) if (keepLocalTime) { const newOffset = ins.utcOffset() @@ -120,7 +120,7 @@ export default (o, c, d) => { return oldStartOf.call(this, units, startOf) } - const withoutTz = d(this.format('YYYY-MM-DD HH:mm:ss:SSS')) + const withoutTz = d(this.format('YYYY-MM-DD HH:mm:ss:SSS'), { locale: this.$L }) const startOfWithoutTz = oldStartOf.call(withoutTz, units, startOf) return startOfWithoutTz.tz(this.$x.$timezone, true) } diff --git a/test/constructor.test.js b/test/constructor.test.js index b14b2fec4..66cdbfc68 100644 --- a/test/constructor.test.js +++ b/test/constructor.test.js @@ -13,6 +13,14 @@ it('supports instanceof dayjs', () => { expect(dayjs() instanceof dayjs).toBeTruthy() }) +it('$isDayjsObject', () => { + const mockOtherVersionDayjsObj = { + $isDayjsObject: true + } + expect(dayjs.isDayjs(mockOtherVersionDayjsObj)).toBeTruthy() +}) + it('does not break isDayjs', () => { expect(dayjs.isDayjs(dayjs())).toBeTruthy() + expect(dayjs.isDayjs(new Date())).toBeFalsy() }) diff --git a/test/display.test.js b/test/display.test.js index 7eb48fe82..ce1f47893 100644 --- a/test/display.test.js +++ b/test/display.test.js @@ -260,3 +260,11 @@ it('As JSON -> toJSON', () => { it('As ISO 8601 String -> toISOString e.g. 2013-02-04T22:44:30.652Z', () => { expect(dayjs().toISOString()).toBe(moment().toISOString()) }) + +it('Year 1 formatted with YYYY should pad with zeroes', () => { + const date = new Date(1, 0, 1) + date.setUTCFullYear(1) // Required because 0-99 are parsed as 19xx in JS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#year + const res = dayjs(date).format('YYYY') + expect(res.slice(0, 3)).toBe('000') // because of timezone, the result might be 0000 0001 or 0002 + expect(res).toBe(moment(date).format('YYYY')) +}) diff --git a/test/issues/issue2027.correct-order.test.js b/test/issues/issue2027.correct-order.test.js new file mode 100644 index 000000000..3d9d6300c --- /dev/null +++ b/test/issues/issue2027.correct-order.test.js @@ -0,0 +1,78 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import duration from '../../src/plugin/duration' +import objectSupport from '../../src/plugin/objectSupport' + +dayjs.extend(objectSupport) +dayjs.extend(duration) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +// issue 2027 +describe('issue 2027 - order objectSupport > Duration', () => { + it('add Duration object returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const durationToAdd = dayjs.duration(6, 'hours') + const testDate = baseDate.add(durationToAdd) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') + }) + it('subtract Duration object returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const durationToAdd = dayjs.duration(6, 'hours') + const testDate = baseDate.subtract(durationToAdd) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') + }) + + it('add number with unit returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.add(6, 'hours') + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') + }) + it('subtract number with unit returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.subtract(6, 'hours') + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') + }) + + it('parse string returns correct date', () => { + const testDate = dayjs('2022-06-26T14:01:02.003') + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') + }) + it('parse object returns correct date', () => { + const testDate = dayjs({ + year: '2022', + month: '05', + day: '26', + hour: '14', + minute: '01', + second: '02', + millisecond: '003' + }) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') + }) + + it('set hour with number returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.hour(10) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') + }) + it('set hour with object returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.set({ hour: '10' }) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') + }) +}) diff --git a/test/issues/issue2027.swapped-order.test.js b/test/issues/issue2027.swapped-order.test.js new file mode 100644 index 000000000..62a969e49 --- /dev/null +++ b/test/issues/issue2027.swapped-order.test.js @@ -0,0 +1,79 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import duration from '../../src/plugin/duration' +import objectSupport from '../../src/plugin/objectSupport' + +dayjs.extend(duration) +dayjs.extend(objectSupport) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +// issue 2027 +describe('issue 2027 - order objectSupport > Duration', () => { + it('add Duration object returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const durationToAdd = dayjs.duration(6, 'hours') + const testDate = baseDate.add(durationToAdd) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') + }) + + it('subtract Duration object returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const durationToAdd = dayjs.duration(6, 'hours') + const testDate = baseDate.subtract(durationToAdd) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') + }) + + it('add number with unit returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.add(6, 'hours') + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 20:01:02.003') + }) + it('subtract number with unit returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.subtract(6, 'hours') + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 08:01:02.003') + }) + + it('parse string returns correct date', () => { + const testDate = dayjs('2022-06-26T14:01:02.003') + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') + }) + it('parse object returns correct date', () => { + const testDate = dayjs({ + year: '2022', + month: '05', + day: '26', + hour: '14', + minute: '01', + second: '02', + millisecond: '003' + }) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 14:01:02.003') + }) + + it('set hour with number returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.hour(10) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') + }) + it('set hour with object returns correct date', () => { + const baseDate = dayjs('2022-06-26T14:01:02.003') + const testDate = baseDate.set({ hour: '10' }) + + expect(testDate.format('YYYY-MM-DD HH:mm:ss.SSS')).toBe('2022-06-26 10:01:02.003') + }) +}) diff --git a/test/locale/ar-dz.test.js b/test/locale/ar-dz.test.js new file mode 100644 index 000000000..532e5f8eb --- /dev/null +++ b/test/locale/ar-dz.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-dz' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-dz').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-dz').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-dz').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-dz').format('A')).toEqual('م') +}) diff --git a/test/locale/ar-iq.test.js b/test/locale/ar-iq.test.js new file mode 100644 index 000000000..810723da3 --- /dev/null +++ b/test/locale/ar-iq.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-iq' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-iq').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-iq').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-iq').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-iq').format('A')).toEqual('م') +}) diff --git a/test/locale/ar-kw.test.js b/test/locale/ar-kw.test.js new file mode 100644 index 000000000..8a8e14933 --- /dev/null +++ b/test/locale/ar-kw.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-kw' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-kw').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-kw').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-kw').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-kw').format('A')).toEqual('م') +}) diff --git a/test/locale/ar-ly.test.js b/test/locale/ar-ly.test.js new file mode 100644 index 000000000..927675136 --- /dev/null +++ b/test/locale/ar-ly.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-ly' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-ly').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-ly').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-ly').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-ly').format('A')).toEqual('م') +}) diff --git a/test/locale/ar-ma.test.js b/test/locale/ar-ma.test.js new file mode 100644 index 000000000..e08ab86d1 --- /dev/null +++ b/test/locale/ar-ma.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-ma' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-ma').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-ma').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-ma').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-ma').format('A')).toEqual('م') +}) diff --git a/test/locale/ar-sa.test.js b/test/locale/ar-sa.test.js new file mode 100644 index 000000000..1936f5086 --- /dev/null +++ b/test/locale/ar-sa.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-sa' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-sa').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-sa').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-sa').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-sa').format('A')).toEqual('م') +}) diff --git a/test/locale/ar-tn.test.js b/test/locale/ar-tn.test.js new file mode 100644 index 000000000..7c73dfcd9 --- /dev/null +++ b/test/locale/ar-tn.test.js @@ -0,0 +1,23 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/ru' +import locale from '../../src/locale/ar-tn' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Meridiem', () => { + dayjs.locale(locale) + expect(dayjs('2020-01-01 03:00:00').locale('ar-tn').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 11:00:00').locale('ar-tn').format('A')).toEqual('ص') + expect(dayjs('2020-01-01 16:00:00').locale('ar-tn').format('A')).toEqual('م') + expect(dayjs('2020-01-01 20:00:00').locale('ar-tn').format('A')).toEqual('م') +}) diff --git a/test/locale/ar.test.js b/test/locale/ar.test.js index 3f9f60f0c..2b5a57d29 100644 --- a/test/locale/ar.test.js +++ b/test/locale/ar.test.js @@ -50,3 +50,13 @@ it('RelativeTime: Time from X gets formatted', () => { .toBe(t[2]) }) }) + +it('Format meridiem with locale function', () => { + for (let i = 0; i <= 23; i += 1) { + const hour = dayjs() + .startOf('day') + .add(i, 'hour') + const meridiem = i > 12 ? 'م' : 'ص' + expect(hour.locale('ar').format('A')).toBe(`${meridiem}`) + } +}) diff --git a/test/locale/sl.test.js b/test/locale/sl.test.js new file mode 100644 index 000000000..672d6064b --- /dev/null +++ b/test/locale/sl.test.js @@ -0,0 +1,82 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/sl' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Slovenian locale relative time in past and future', () => { + const cases = [ + [1, 's', 'čez nekaj sekund', 'nekaj sekund'], + [-1, 's', 'pred nekaj sekundami', 'nekaj sekund'], + [1, 'm', 'čez eno minuto', 'ena minuta'], + [-1, 'm', 'pred eno minuto', 'ena minuta'], + [2, 'm', 'čez 2 minuti', '2 minuti'], + [-2, 'm', 'pred 2 minutama', '2 minuti'], + [3, 'm', 'čez 3 minute', '3 minute'], + [-3, 'm', 'pred 3 minutami', '3 minute'], + [5, 'm', 'čez 5 minut', '5 minut'], + [-5, 'm', 'pred 5 minutami', '5 minut'], + [1, 'h', 'čez eno uro', 'ena ura'], + [-1, 'h', 'pred eno uro', 'ena ura'], + [2, 'h', 'čez 2 uri', '2 uri'], + [-2, 'h', 'pred 2 urama', '2 uri'], + [3, 'h', 'čez 3 ure', '3 ure'], + [-3, 'h', 'pred 3 urami', '3 ure'], + [5, 'h', 'čez 5 ur', '5 ur'], + [-5, 'h', 'pred 5 urami', '5 ur'], + [1, 'd', 'čez en dan', 'en dan'], + [-1, 'd', 'pred enim dnem', 'en dan'], + [2, 'd', 'čez 2 dneva', '2 dneva'], + [-2, 'd', 'pred 2 dnevoma', '2 dneva'], + [3, 'd', 'čez 3 dni', '3 dni'], + [-3, 'd', 'pred 3 dnevi', '3 dni'], + [5, 'd', 'čez 5 dni', '5 dni'], + [-5, 'd', 'pred 5 dnevi', '5 dni'], + [1, 'M', 'čez en mesec', 'en mesec'], + [-1, 'M', 'pred enim mesecem', 'en mesec'], + [2, 'M', 'čez 2 meseca', '2 meseca'], + [-2, 'M', 'pred 2 mesecema', '2 meseca'], + [3, 'M', 'čez 3 mesece', '3 mesece'], + [-3, 'M', 'pred 3 meseci', '3 mesece'], + [5, 'M', 'čez 5 mesecev', '5 mesecev'], + [-5, 'M', 'pred 5 meseci', '5 mesecev'], + [1, 'y', 'čez eno leto', 'eno leto'], + [-1, 'y', 'pred enim letom', 'eno leto'], + [2, 'y', 'čez 2 leti', '2 leti'], + [-2, 'y', 'pred 2 letoma', '2 leti'], + [3, 'y', 'čez 3 leta', '3 leta'], + [-3, 'y', 'pred 3 leti', '3 leta'], + [5, 'y', 'čez 5 let', '5 let'], + [-5, 'y', 'pred 5 leti', '5 let'] + // these are rounded + // if user decides to change rounding then it would be good to test them also + // [102, 's', 'čez 102 sekundi', '102 sekundi'], + // [-102, 's', 'pred 102 sekundama', '102 sekundi'], + // [103, 's', 'čez 103 sekunde', '103 sekunde'], + // [-103, 's', 'pred 103 sekundami', '103 sekunde'], + // [114, 's', 'čez 114 sekund', '114 sekund'], + // [-114, 's', 'pred 114 sekundami', '114 sekund'], + // [-102, 'm', 'čez 102 minuti', '102 minuti'], + // [-102, 'm', 'pred 102 minutama', '102 minuti'], + // [103, 'm', 'čez 103 minute', '103 minute'], + // [-103, 'm', 'pred 103 minutami', '103 minute'], + // [114, 'm', 'čez 114 minut', '114 minut'], + // [-114, 'm', 'pred 114 minutami', '114 minut'] + ] + + cases.forEach((c) => { + // With suffix + expect(dayjs().add(c[0], c[1]).locale('sl').fromNow()).toBe(c[2]) + // Without suffix + expect(dayjs().add(c[0], c[1]).locale('sl').fromNow(true)).toBe(c[3]) + }) +}) diff --git a/test/locale/zh-hk.test.js b/test/locale/zh-hk.test.js new file mode 100644 index 000000000..5b65c6cfc --- /dev/null +++ b/test/locale/zh-hk.test.js @@ -0,0 +1,27 @@ +import dayjs from '../../src' +import advancedFormat from '../../src/plugin/advancedFormat' +import weekOfYear from '../../src/plugin/weekOfYear' +import '../../src/locale/zh' +import '../../src/locale/zh-cn' +import '../../src/locale/zh-hk' +import '../../src/locale/zh-tw' + +dayjs.extend(advancedFormat).extend(weekOfYear) + +const zh = dayjs().locale('zh') +const zhCN = dayjs().locale('zh-cn') +const zhHK = dayjs().locale('zh-hk') +const zhTW = dayjs().locale('zh-tw') + +test('ordinal', () => { + expect(zh.format('wo')).toEqual(`${zh.format('w')}周`) + expect(zhCN.format('wo')).toEqual(`${zhCN.format('w')}周`) + expect(zhHK.format('wo')).toEqual(`${zhHK.format('w')}週`) + expect(zhTW.format('wo')).toEqual(`${zhTW.format('w')}週`) +}) + +test('Meridiem', () => { + for (let i = 0; i <= 24; i += 1) { + expect(zh.add(i, 'hour').format('A')).toBe(zhCN.add(i, 'hour').format('A')) + } +}) diff --git a/test/locale/zh-tw.test.js b/test/locale/zh-tw.test.js new file mode 100644 index 000000000..57a3f1079 --- /dev/null +++ b/test/locale/zh-tw.test.js @@ -0,0 +1,21 @@ +import dayjs from '../../src' +import advancedFormat from '../../src/plugin/advancedFormat' +import weekOfYear from '../../src/plugin/weekOfYear' +import '../../src/locale/zh' +import '../../src/locale/zh-tw' + +dayjs.extend(advancedFormat).extend(weekOfYear) + +const zh = dayjs().locale('zh') +const zhTW = dayjs().locale('zh-tw') + +test('ordinal', () => { + expect(zh.format('wo')).toEqual(`${zh.format('w')}周`) + expect(zhTW.format('wo')).toEqual(`${zhTW.format('w')}週`) +}) + +test('Meridiem', () => { + for (let i = 0; i <= 24; i += 1) { + expect(zh.add(i, 'hour').format('A')).toBe(zhTW.add(i, 'hour').format('A')) + } +}) diff --git a/test/plugin/advancedFormat.test.js b/test/plugin/advancedFormat.test.js index 955f94032..2905538f6 100644 --- a/test/plugin/advancedFormat.test.js +++ b/test/plugin/advancedFormat.test.js @@ -8,6 +8,7 @@ import weekYear from '../../src/plugin/weekYear' import timezone from '../../src/plugin/timezone' import utc from '../../src/plugin/utc' import '../../src/locale/zh-cn' +import '../../src/locale/nl' dayjs.extend(utc) dayjs.extend(timezone) @@ -51,12 +52,16 @@ it('Format Day of Month Do 1 - 31', () => { expect(dayjs(d).format('Do')).toBe(moment(d).format('Do')) d = '2018-05-04 00:00:00.000' expect(dayjs(d).format('Do')).toBe(moment(d).format('Do')) + d = '2018-05-08 00:00:00.000' + expect(dayjs(d).locale('nl').format('Do')).toBe(moment(d).locale('nl').format('Do')) d = '2018-05-11' expect(dayjs(d).format('Do')).toBe(moment(d).format('Do')) d = '2018-05-12' expect(dayjs(d).format('Do')).toBe(moment(d).format('Do')) d = '2018-05-13' expect(dayjs(d).format('Do')).toBe(moment(d).format('Do')) + d = '2018-05-19 00:00:00.000' + expect(dayjs(d).locale('nl').format('Do')).toBe(moment(d).locale('nl').format('Do')) d = '2018-05-22' expect(dayjs(d).format('Do')).toBe(moment(d).format('Do')) }) diff --git a/test/plugin/bigIntSupport.test.js b/test/plugin/bigIntSupport.test.js new file mode 100644 index 000000000..b2e70866f --- /dev/null +++ b/test/plugin/bigIntSupport.test.js @@ -0,0 +1,30 @@ +import MockDate from 'mockdate' +import moment from 'moment' +import dayjs from '../../src' +import bigIntSupport from '../../src/plugin/bigIntSupport' + +dayjs.extend(bigIntSupport) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +/* global BigInt */ + +it('Parse BigInt ts and tsms', () => { + const tsms = 1666310421101 + const tsmsBig = BigInt(tsms) + const ts = 1666311003 + const tsBig = BigInt(ts) + const momentTsms = moment(tsms) + const momentTs = moment.unix(ts) + expect(dayjs(tsms).valueOf()).toBe(momentTsms.valueOf()) + expect(dayjs(tsms).valueOf()).toBe(dayjs(tsmsBig).valueOf()) + expect(dayjs.unix(ts).valueOf()).toBe(momentTs.valueOf()) + expect(dayjs.unix(tsBig).valueOf()).toBe(dayjs.unix(tsBig).valueOf()) +}) + diff --git a/test/plugin/duration.test.js b/test/plugin/duration.test.js index 2e804691c..3e726af91 100644 --- a/test/plugin/duration.test.js +++ b/test/plugin/duration.test.js @@ -67,6 +67,25 @@ describe('Creating', () => { ms: -1 }).toISOString()).toBe('-PT0.001S') }) + it('convert to milliseconds', () => { + expect(+dayjs.duration(100)).toBe(100) + }) + it('handles rounding to millisecond precision', () => { + expect(dayjs.duration(2 / 3).toISOString()).toBe('PT0.001S') + }) + it('should handle round with millisecond precision when negative', () => { + expect(dayjs.duration(1000.5).toISOString()).toBe('PT1.001S') + expect(dayjs.duration(-1000.5).toISOString()).toBe('-PT1S') + }) + it('should handle floating point rounding errors', () => { + // An example of this is when adding 2 to 0.812 seconds, which is how + // the seconds component is calculated in .toISOString(). + // > 2 + 0.812 + // 2.8120000000000003 + expect(dayjs.duration(-2812).toISOString()).toBe('-PT2.812S') // was -PT2.8120000000000003S + expect(dayjs.duration(3121632.27382247).toISOString()).toBe('PT52M1.632S') // was PT52M1.6320000000000001S + expect(dayjs.duration(7647826.525774224).toISOString()).toBe('PT2H7M27.827S') // was PT2H7M27.826999999999998S + }) }) describe('Parse ISO string', () => { @@ -82,8 +101,9 @@ describe('Parse ISO string', () => { it('ISO string with week', () => { const d = dayjs.duration('P2M3W4D') expect(d.toISOString()).toBe('P2M25D') - expect(d.asDays()).toBe(85) // moment 85, count 2M as 61 days - expect(d.asWeeks()).toBe(12.142857142857142) // moment 12.285714285714286 + expect(d.asDays()).toBe(85.83333333333333) // moment 86, count 2M as 61 days + expect(d.asWeeks()).toBe(12.261904761904763) // moment 12.285714285714286 + expect(d.asMonths()).toBe(2.8219178082191783) // moment 2.8213721020965523 }) it('Invalid ISO string', () => { expect(dayjs.duration('Invalid').toISOString()).toBe('P0D') @@ -175,10 +195,20 @@ describe('Add', () => { expect(a.add({ days: 5 }).days()).toBe(6) }) +describe('Add to a dayjs()', () => { + const a = dayjs() + const b = dayjs.duration({ hours: 7, minutes: 10 }) + expect(a.add(b)).toEqual(a.add(7, 'hours').add(10, 'minutes')) +}) + test('Add duration', () => { const a = dayjs('2020-10-01') const days = dayjs.duration(2, 'days') expect(a.add(days).format('YYYY-MM-DD')).toBe('2020-10-03') + + const b = dayjs('2023-02-01 00:00:00') + const p = dayjs.duration('P1Y1M1DT1H1M1S') + expect(b.add(p).format('YYYY-MM-DD HH:mm:ss')).toBe('2024-03-02 01:01:01') }) describe('Subtract', () => { @@ -191,6 +221,10 @@ test('Subtract duration', () => { const a = dayjs('2020-10-20') const days = dayjs.duration(2, 'days') expect(a.subtract(days).format('YYYY-MM-DD')).toBe('2020-10-18') + + const b = dayjs('2023-03-02 02:02:02') + const p = dayjs.duration('P1Y1M1DT1H1M1S') + expect(b.subtract(p).format('YYYY-MM-DD HH:mm:ss')).toBe('2022-02-01 01:01:01') }) describe('Seconds', () => { diff --git a/test/plugin/isSameOrAfter.test.js b/test/plugin/isSameOrAfter.test.js index fd504c2f8..f5533d763 100644 --- a/test/plugin/isSameOrAfter.test.js +++ b/test/plugin/isSameOrAfter.test.js @@ -49,6 +49,13 @@ test('is same or after without units', () => { expect(+m).toEqual(+mCopy, 'isSameOrAfter second should not change moment') }) +test('is same or after without date', () => { + const past = dayjs().subtract(1, 'day') + const future = dayjs().add(1, 'day') + expect(past.isSameOrAfter()).toBe(false, 'past is before now') + expect(future.isSameOrAfter()).toBe(true, 'future is not before now') +}) + test('is same or after month', () => { const m = dayjs(new Date(2011, 2, 3, 4, 5, 6, 7)) const mCopy = dayjs(m) diff --git a/test/plugin/isSameOrBefore.test.js b/test/plugin/isSameOrBefore.test.js index a8e18215a..3ceff55fa 100644 --- a/test/plugin/isSameOrBefore.test.js +++ b/test/plugin/isSameOrBefore.test.js @@ -34,6 +34,13 @@ test('is same or before without units', () => { expect(+m).toEqual(+mCopy, 'isSameOrBefore second should not change moment') }) +test('is same or before without date', () => { + const past = dayjs().subtract(1, 'day') + const future = dayjs().add(1, 'day') + expect(past.isSameOrBefore()).toBe(true, 'past is before now') + expect(future.isSameOrBefore()).toBe(false, 'future is not before now') +}) + test('is same or before year', () => { const m = dayjs(new Date(2011, 1, 2, 3, 4, 5, 6)) const mCopy = dayjs(m) diff --git a/test/plugin/minMax.test.js b/test/plugin/minMax.test.js index eeef92063..f8a508001 100644 --- a/test/plugin/minMax.test.js +++ b/test/plugin/minMax.test.js @@ -55,3 +55,17 @@ it('If Invalid Date return Invalid Date', () => { expect(dayjs.min([arg1, arg2, arg3, arg4]).format()) .toBe(arg4.format()) }) + +it('Ignore if exists an "null" argument', () => { + expect(dayjs.max(null, null, arg1, arg2, null, arg3).format()) + .toBe(arg1.format()) + expect(dayjs.min([null, null, arg1, arg2, null, arg3]).format()) + .toBe(arg3.format()) +}) + +it('Return the only date if just provided one argument', () => { + expect(dayjs.max(arg1).format()) + .toBe(arg1.format()) + expect(dayjs.min([arg1]).format()) + .toBe(arg1.format()) +}) diff --git a/test/plugin/objectSupport.test.js b/test/plugin/objectSupport.test.js index 06b10f9dc..abf046d34 100755 --- a/test/plugin/objectSupport.test.js +++ b/test/plugin/objectSupport.test.js @@ -140,6 +140,12 @@ it('Constructor from Object UTC', () => { expect(moment.utc(tests[i][0]).format(fmt)).toBe(result) } }) + +it('Constructor from null should return Invalid Date', () => { + expect(dayjs(null).isValid()).toBe(false) + expect(moment(null).isValid()).toBe(false) +}) + it('Set from Object', () => { for (let i = 0; i < tests.length; i += 1) { expect(dayjs(now).set(tests[i][0]).format(fmt)).toBe(moment(now).set(tests[i][0]).format(fmt)) @@ -384,3 +390,11 @@ it('add decimal values of days and months', () => { expect(dayjs([2016, 7, 1]).add(1.6, 'years').format('YYYY-MM-DD')).toBe('2017-07-01') expect(dayjs([2016, 1, 1]).add(1.1, 'quarters').format('YYYY-MM-DD')).toBe('2016-04-01') }) + +it('returns valid date on undefined', () => { + expect(dayjs().isValid()).toBe(true) +}) + +it('returns invalid date on null', () => { + expect(dayjs(null).isValid()).toBe(false) +}) diff --git a/test/plugin/timezone.test.js b/test/plugin/timezone.test.js index 2b28cc309..c4529c6c8 100644 --- a/test/plugin/timezone.test.js +++ b/test/plugin/timezone.test.js @@ -318,4 +318,15 @@ describe('startOf and endOf', () => { const endOfDay = originalDay.endOf('day') expect(endOfDay.valueOf()).toEqual(originalDay.valueOf()) }) + + it('preserves locality when tz is called', () => { + const tzWithoutLocality = dayjs.tz('2023-02-17 00:00:00', NY) + const tzWithLocality = dayjs.tz('2023-02-17 00:00:00', NY).locale({ + name: 'locale_test', + weekStart: 3 + }) + + expect(tzWithoutLocality.startOf('week').format('YYYY-MM-DD')).toEqual('2023-02-12') + expect(tzWithLocality.startOf('week').format('YYYY-MM-DD')).toEqual('2023-02-15') + }) }) diff --git a/types/index.d.ts b/types/index.d.ts index 1ac6c8dac..766bd7943 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -382,7 +382,7 @@ declare namespace dayjs { * * Docs: https://day.js.org/docs/en/query/is-before */ - isBefore(date: ConfigType, unit?: OpUnitType): boolean + isBefore(date?: ConfigType, unit?: OpUnitType): boolean /** * This indicates whether the Day.js object is the same as the other supplied date-time. * ``` @@ -394,7 +394,7 @@ declare namespace dayjs { * ``` * Docs: https://day.js.org/docs/en/query/is-same */ - isSame(date: ConfigType, unit?: OpUnitType): boolean + isSame(date?: ConfigType, unit?: OpUnitType): boolean /** * This indicates whether the Day.js object is after the other supplied date-time. * ``` @@ -408,7 +408,7 @@ declare namespace dayjs { * * Docs: https://day.js.org/docs/en/query/is-after */ - isAfter(date: ConfigType, unit?: OpUnitType): boolean + isAfter(date?: ConfigType, unit?: OpUnitType): boolean locale(): string diff --git a/types/plugin/bigIntSupport.d.ts b/types/plugin/bigIntSupport.d.ts new file mode 100644 index 000000000..d9f2f394e --- /dev/null +++ b/types/plugin/bigIntSupport.d.ts @@ -0,0 +1,11 @@ +import { PluginFunc } from 'dayjs' + +declare module 'dayjs' { + interface ConfigTypeMap { + bigIntSupport: BigInt + } + export function unix(t: BigInt): Dayjs +} + +declare const plugin: PluginFunc +export = plugin diff --git a/types/plugin/isSameOrAfter.d.ts b/types/plugin/isSameOrAfter.d.ts index 1c8c26497..916bc801c 100644 --- a/types/plugin/isSameOrAfter.d.ts +++ b/types/plugin/isSameOrAfter.d.ts @@ -5,6 +5,6 @@ export = plugin declare module 'dayjs' { interface Dayjs { - isSameOrAfter(date: ConfigType, unit?: OpUnitType): boolean + isSameOrAfter(date?: ConfigType, unit?: OpUnitType): boolean } } diff --git a/types/plugin/isSameOrBefore.d.ts b/types/plugin/isSameOrBefore.d.ts index 1df5492c0..d52b0955c 100644 --- a/types/plugin/isSameOrBefore.d.ts +++ b/types/plugin/isSameOrBefore.d.ts @@ -5,6 +5,6 @@ export = plugin declare module 'dayjs' { interface Dayjs { - isSameOrBefore(date: ConfigType, unit?: OpUnitType): boolean + isSameOrBefore(date?: ConfigType, unit?: OpUnitType): boolean } } diff --git a/types/plugin/isoWeek.d.ts b/types/plugin/isoWeek.d.ts index 26c591ba6..3f4d88f62 100644 --- a/types/plugin/isoWeek.d.ts +++ b/types/plugin/isoWeek.d.ts @@ -18,10 +18,10 @@ declare module 'dayjs' { endOf(unit: ISOUnitType): Dayjs - isSame(date: ConfigType, unit?: ISOUnitType): boolean + isSame(date?: ConfigType, unit?: ISOUnitType): boolean - isBefore(date: ConfigType, unit?: ISOUnitType): boolean + isBefore(date?: ConfigType, unit?: ISOUnitType): boolean - isAfter(date: ConfigType, unit?: ISOUnitType): boolean + isAfter(date?: ConfigType, unit?: ISOUnitType): boolean } } diff --git a/types/plugin/minMax.d.ts b/types/plugin/minMax.d.ts index f1673500c..4c5f6dcd7 100644 --- a/types/plugin/minMax.d.ts +++ b/types/plugin/minMax.d.ts @@ -4,8 +4,8 @@ declare const plugin: PluginFunc export = plugin declare module 'dayjs' { - export function max(dayjs: Dayjs[]): Dayjs - export function max(...dayjs: Dayjs[]): Dayjs - export function min(dayjs: Dayjs[]): Dayjs - export function min(...dayjs: Dayjs[]): Dayjs + export function max(dayjs: Dayjs[]): Dayjs | null + export function max(...dayjs: Dayjs[]): Dayjs | null + export function min(dayjs: Dayjs[]): Dayjs | null + export function min(...dayjs: Dayjs[]): Dayjs | null } diff --git a/types/plugin/objectSupport.d.ts b/types/plugin/objectSupport.d.ts index 0d3cf05b4..ad0e1ffea 100755 --- a/types/plugin/objectSupport.d.ts +++ b/types/plugin/objectSupport.d.ts @@ -9,4 +9,40 @@ declare module 'dayjs' { add(argument: object): Dayjs subtract(argument: object): Dayjs } + + interface ConfigTypeMap { + objectSupport: { + years?: number | string; + year?: number | string; + y?: number | string; + + months?: number | string; + month?: number | string; + M?: number | string; + + days?: number | string; + day?: number | string; + d?: number | string; + + dates?: number | string; + date?: number | string; + D?: number | string; + + hours?: number | string; + hour?: number | string; + h?: number | string; + + minutes?: number | string; + minute?: number | string; + m?: number | string; + + seconds?: number | string; + second?: number | string; + s?: number | string; + + milliseconds?: number | string; + millisecond?: number | string; + ms?: number | string; + } + } } diff --git a/types/plugin/quarterOfYear.d.ts b/types/plugin/quarterOfYear.d.ts index 8a9cc1e3d..317e0ad2d 100644 --- a/types/plugin/quarterOfYear.d.ts +++ b/types/plugin/quarterOfYear.d.ts @@ -17,10 +17,10 @@ declare module 'dayjs' { endOf(unit: QUnitType | OpUnitType): Dayjs - isSame(date: ConfigType, unit?: QUnitType): boolean + isSame(date?: ConfigType, unit?: QUnitType): boolean - isBefore(date: ConfigType, unit?: QUnitType): boolean + isBefore(date?: ConfigType, unit?: QUnitType): boolean - isAfter(date: ConfigType, unit?: QUnitType): boolean + isAfter(date?: ConfigType, unit?: QUnitType): boolean } } diff --git a/types/plugin/timezone.d.ts b/types/plugin/timezone.d.ts index d504f6927..049bb0870 100644 --- a/types/plugin/timezone.d.ts +++ b/types/plugin/timezone.d.ts @@ -10,7 +10,7 @@ declare module 'dayjs' { } interface DayjsTimezone { - (date: ConfigType, timezone?: string): Dayjs + (date?: ConfigType, timezone?: string): Dayjs (date: ConfigType, format: string, timezone?: string): Dayjs guess(): string setDefault(timezone?: string): void