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/README.md b/README.md index ca0443f1e..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)
אלטרנטיבה מהירה ל-Moment.js ששוקלת רק 2kB עם אותן יכולות מודרניות
+
+
+עברית | [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 מורשה לשימוש עם [רישיון 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)
{
+ 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 +348,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/plugin/duration/index.js b/src/plugin/duration/index.js
index 5d4cc6aa8..26bc75e34 100644
--- a/src/plugin/duration/index.js
+++ b/src/plugin/duration/index.js
@@ -257,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()
@@ -268,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 86a978dfc..ce1f47893 100644
--- a/test/display.test.js
+++ b/test/display.test.js
@@ -264,11 +264,7 @@ it('As ISO 8601 String -> toISOString e.g. 2013-02-04T22:44:30.652Z', () => {
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
- expect(dayjs(date).format('YYYY')).toBe('0001')
-})
-
-it('Year 1 formatting matches moment format', () => {
- const date = new Date(1, 0, 1)
- date.setUTCFullYear(1)
- expect(dayjs(date).format('YYYY')).toBe(moment(date).format('YYYY'))
+ 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/plugin/duration.test.js b/test/plugin/duration.test.js
index 8a7e0e6cd..4a4753931 100644
--- a/test/plugin/duration.test.js
+++ b/test/plugin/duration.test.js
@@ -182,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', () => {
@@ -194,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/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/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
}