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 2b17216d5..000000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: node_js -cache: - directories: - - ~/.npm - - node_modules -node_js: - - '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 7b5a4adf1..6252fd8eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +## [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) diff --git a/README.md b/README.md index dc6ca105e..3a855a9c3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -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) +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)

+ + +                  + + + +                  - -         - +          - +          - +          @@ -130,10 +136,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..cd168577f 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)

+ +עברית | [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..a708a03bb 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)| [עברית](./docs/he/README-he.md)

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/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/fa.js b/src/locale/fa.js index cf338279f..cbcd13c1e 100644 --- a/src/locale/fa.js +++ b/src/locale/fa.js @@ -4,11 +4,11 @@ import dayjs from 'dayjs' const locale = { name: 'fa', weekdays: 'یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه'.split('_'), - weekdaysShort: 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), + weekdaysShort: 'یک‌_دو_سه‌_چه_پن_جم_شن'.split('_'), weekdaysMin: 'ی_د_س_چ_پ_ج_ش'.split('_'), weekStart: 6, - months: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - monthsShort: 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), + months: 'فروردین_اردیبهشت_خرداد_تیر_مرداد_شهریور_مهر_آبان_آذر_دی_بهمن_اسفند'.split('_'), + monthsShort: 'فرو_ارد_خرد_تیر_مرد_شهر_مهر_آبا_آذر_دی_بهم_اسف'.split('_'), ordinal: n => n, formats: { LT: 'HH:mm', @@ -20,7 +20,7 @@ const locale = { }, relativeTime: { future: 'در %s', - past: '%s پیش', + past: '%s قبل', s: 'چند ثانیه', m: 'یک دقیقه', mm: '%d دقیقه', diff --git a/src/locale/zh-tw.js b/src/locale/zh-tw.js index 5b194c63f..709f70cff 100644 --- a/src/locale/zh-tw.js +++ b/src/locale/zh-tw.js @@ -42,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..26bc75e34 100644 --- a/src/plugin/duration/index.js +++ b/src/plugin/duration/index.js @@ -235,6 +235,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 +257,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 +277,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 650166606..bd32358e9 100644 --- a/src/plugin/objectSupport/index.js +++ b/src/plugin/objectSupport/index.js @@ -1,6 +1,6 @@ export default (o, c, dayjs) => { const proto = c.prototype - const isObject = obj => !(obj instanceof Date) && !(obj instanceof Array) + 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) 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/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/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..4a4753931 100644 --- a/test/plugin/duration.test.js +++ b/test/plugin/duration.test.js @@ -67,6 +67,9 @@ describe('Creating', () => { ms: -1 }).toISOString()).toBe('-PT0.001S') }) + it('convert to milliseconds', () => { + expect(+dayjs.duration(100)).toBe(100) + }) }) describe('Parse ISO string', () => { @@ -179,6 +182,10 @@ 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 +198,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/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/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