Skip to content

Commit 52dfb13

Browse files
authoredApr 30, 2020
fix: Add plugin objectSupport (#887)
1 parent 058d624 commit 52dfb13

File tree

3 files changed

+419
-0
lines changed

3 files changed

+419
-0
lines changed
 

‎src/plugin/objectSupport/index.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
export default (o, c) => {
2+
const proto = c.prototype
3+
const isObject = obj => !(obj instanceof Date) && !(obj instanceof Array) && obj instanceof Object
4+
const prettyUnit = (u) => {
5+
const unit = proto.$utils().p(u)
6+
return unit === 'date' ? 'day' : unit
7+
}
8+
const parseDate = (cfg) => {
9+
const { date, utc } = cfg
10+
const $d = {}
11+
if (isObject(date)) {
12+
Object.keys(date).forEach((k) => {
13+
$d[prettyUnit(k)] = date[k]
14+
})
15+
const y = $d.year || 1970
16+
const M = $d.month - 1 || 0
17+
const d = $d.day || 1
18+
const h = $d.hour || 0
19+
const m = $d.minute || 0
20+
const s = $d.second || 0
21+
const ms = $d.millisecond || 0
22+
if (utc) {
23+
return new Date(Date.UTC(y, M, d, h, m, s, ms))
24+
}
25+
return new Date(y, M, d, h, m, s, ms)
26+
}
27+
return date
28+
}
29+
30+
const oldParse = proto.parse
31+
proto.parse = function (cfg) {
32+
cfg.date = parseDate.bind(this)(cfg)
33+
oldParse.bind(this)(cfg)
34+
}
35+
36+
const oldSet = proto.set
37+
const oldAdd = proto.add
38+
39+
const callObject = function (call, argument, string, offset = 1) {
40+
if (argument instanceof Object) {
41+
const keys = Object.keys(argument)
42+
let chain = this
43+
keys.forEach((key) => {
44+
chain = call.bind(chain)(argument[key] * offset, key)
45+
})
46+
return chain
47+
}
48+
return call.bind(this)(argument * offset, string)
49+
}
50+
51+
proto.set = function (string, int) {
52+
int = int === undefined ? string : int
53+
return callObject.bind(this)(function (i, s) {
54+
return oldSet.bind(this)(s, i)
55+
}, int, string)
56+
}
57+
proto.add = function (number, string) {
58+
return callObject.bind(this)(oldAdd, number, string)
59+
}
60+
proto.subtract = function (number, string) {
61+
return callObject.bind(this)(oldAdd, number, string, -1)
62+
}
63+
}

‎test/plugin/objectSupport.test.js

+344
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
import moment from 'moment'
2+
import MockDate from 'mockdate'
3+
import dayjs from '../../src'
4+
import objectSupport from '../../src/plugin/objectSupport'
5+
import quarterOfYear from '../../src/plugin/quarterOfYear'
6+
import utc from '../../src/plugin/utc'
7+
8+
dayjs.extend(utc)
9+
dayjs.extend(quarterOfYear)
10+
dayjs.extend(objectSupport)
11+
12+
beforeEach(() => {
13+
MockDate.set(new Date())
14+
})
15+
16+
afterEach(() => {
17+
MockDate.reset()
18+
})
19+
const now = new Date()
20+
const fmt = 'YYYY-MM-DD HH:mm:ss.SSS'
21+
const tests = [
22+
[{ year: 2010 }, '2010-01-01 00:00:00.000'],
23+
[{ year: 2010, month: 1 }, '2010-01-01 00:00:00.000'],
24+
[{ year: 2010, month: 1, day: 12 }, '2010-01-12 00:00:00.000'],
25+
[{ year: 2010, month: 1, date: 12 }, '2010-01-12 00:00:00.000'],
26+
[
27+
{
28+
hour: 15, minute: 25, second: 50, millisecond: 125
29+
},
30+
'1970-01-01 15:25:50.125'],
31+
[
32+
{
33+
year: 2010, month: 1, day: 12, hours: 1
34+
},
35+
'2010-01-12 01:00:00.000'
36+
],
37+
[
38+
{
39+
year: 2010, month: 1, date: 12, hours: 1
40+
},
41+
'2010-01-12 01:00:00.000'
42+
],
43+
[
44+
{
45+
year: 2010, month: 1, day: 12, hours: 1, minutes: 1
46+
},
47+
'2010-01-12 01:01:00.000'
48+
],
49+
[
50+
{
51+
year: 2010, month: 1, date: 12, hours: 1, minutes: 1
52+
},
53+
'2010-01-12 01:01:00.000'
54+
],
55+
[
56+
{
57+
year: 2010,
58+
month: 1,
59+
day: 12,
60+
hours: 1,
61+
minutes: 1,
62+
seconds: 1
63+
},
64+
'2010-01-12 01:01:01.000'
65+
],
66+
[
67+
{
68+
year: 2010,
69+
month: 1,
70+
day: 12,
71+
hours: 1,
72+
minutes: 1,
73+
seconds: 1,
74+
milliseconds: 1
75+
},
76+
'2010-01-12 01:01:01.001'
77+
],
78+
[
79+
{
80+
years: 2010,
81+
months: 1,
82+
days: 14,
83+
hours: 15,
84+
minutes: 25,
85+
seconds: 50,
86+
milliseconds: 125
87+
},
88+
'2010-01-14 15:25:50.125'
89+
],
90+
[
91+
{
92+
year: 2010,
93+
month: 1,
94+
day: 14,
95+
hour: 15,
96+
minute: 25,
97+
second: 50,
98+
millisecond: 125
99+
},
100+
'2010-01-14 15:25:50.125'
101+
],
102+
[
103+
{
104+
y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125
105+
},
106+
'2010-01-14 15:25:50.125'
107+
]
108+
]
109+
it('Constructor from Object', () => {
110+
for (let i = 0; i < tests.length; i += 1) {
111+
expect(dayjs(tests[i][0]).format(fmt)).toBe(tests[i][1])
112+
}
113+
})
114+
115+
it('Constructor from Object UTC', () => {
116+
for (let i = 0; i < tests.length; i += 1) {
117+
expect(dayjs.utc(tests[i][0]).format(fmt)).toBe(tests[i][1])
118+
}
119+
})
120+
it('Set from Object', () => {
121+
for (let i = 0; i < tests.length; i += 1) {
122+
expect(dayjs(now).set(tests[i][0]).format(fmt)).toBe(moment(now).set(tests[i][0]).format(fmt))
123+
}
124+
})
125+
126+
it('add short reverse args', () => {
127+
const a = dayjs({
128+
year: 2011,
129+
month: 9,
130+
date: 12,
131+
hour: 6,
132+
minute: 7,
133+
second: 8,
134+
millisecond: 500
135+
})
136+
expect(a.add({ ms: 50 }).millisecond()).toBe(550)
137+
expect(a.add({ s: 1 }).second()).toBe(9)
138+
expect(a.add({ m: 1 }).minute()).toBe(8)
139+
expect(a.add({ h: 1 }).hour()).toBe(7)
140+
expect(a.add({ d: 1 }).date()).toBe(13)
141+
expect(a.add({ w: 1 }).date()).toBe(19)
142+
expect(a.add({ M: 1 }).month()).toBe(9)
143+
expect(a.add({ y: 1 }).year()).toBe(2012)
144+
expect(a.add({ Q: 1 }).month()).toBe(11)
145+
146+
const b = dayjs([2010, 1, 31]).add({ M: 1 })
147+
const c = dayjs([2010, 2, 28]).subtract({ M: 1 })
148+
const d = dayjs([2010, 2, 28]).subtract({ Q: 1 })
149+
150+
expect(b.month()).toBe(1)
151+
expect(b.date()).toBe(28)
152+
expect(c.month()).toBe(0)
153+
expect(c.date()).toBe(28)
154+
expect(d.month()).toBe(10)
155+
expect(d.date()).toBe(28)
156+
expect(d.year()).toBe(2009)
157+
})
158+
159+
it('add long reverse args', () => {
160+
const a = dayjs({
161+
year: 2011,
162+
month: 9,
163+
date: 12,
164+
hour: 6,
165+
minute: 7,
166+
second: 8,
167+
millisecond: 500
168+
})
169+
170+
expect(a.add({ milliseconds: 50 }).millisecond()).toBe(550)
171+
expect(a.add({ seconds: 1 }).second()).toBe(9)
172+
expect(a.add({ minutes: 1 }).minute()).toBe(8)
173+
expect(a.add({ hours: 1 }).hour()).toBe(7)
174+
expect(a.add({ days: 1 }).date()).toBe(13)
175+
expect(a.add({ weeks: 1 }).date()).toBe(19)
176+
expect(a.add({ months: 1 }).month()).toBe(9)
177+
expect(a.add({ years: 1 }).year()).toBe(2012)
178+
expect(a.add({ quarters: 1 }).month()).toBe(11)
179+
})
180+
181+
it('add long singular reverse args', () => {
182+
const a = dayjs({
183+
year: 2011,
184+
month: 9,
185+
date: 12,
186+
hour: 6,
187+
minute: 7,
188+
second: 8,
189+
millisecond: 500
190+
})
191+
192+
expect(a.add({ millisecond: 50 }).millisecond()).toBe(550)
193+
expect(a.add({ second: 1 }).second()).toBe(9)
194+
expect(a.add({ minute: 1 }).minute()).toBe(8)
195+
expect(a.add({ hour: 1 }).hour()).toBe(7)
196+
expect(a.add({ day: 1 }).date()).toBe(13)
197+
expect(a.add({ week: 1 }).date()).toBe(19)
198+
expect(a.add({ month: 1 }).month()).toBe(9)
199+
expect(a.add({ year: 1 }).year()).toBe(2012)
200+
expect(a.add({ quarter: 1 }).month()).toBe(11)
201+
})
202+
203+
it('add string long', () => {
204+
const a = dayjs({
205+
year: 2011,
206+
month: 9,
207+
date: 12,
208+
hour: 6,
209+
minute: 7,
210+
second: 8,
211+
millisecond: 500
212+
})
213+
214+
expect(a.add(50, 'millisecond').millisecond()).toBe(550)
215+
expect(a.add(1, 'second').second()).toBe(9)
216+
expect(a.add(1, 'minute').minute()).toBe(8)
217+
expect(a.add(1, 'hour').hour()).toBe(7)
218+
expect(a.add(1, 'day').date()).toBe(13)
219+
expect(a.add(1, 'week').date()).toBe(19)
220+
expect(a.add(1, 'month').month()).toBe(9)
221+
expect(a.add(1, 'year').year()).toBe(2012)
222+
expect(a.add(1, 'quarter').month()).toBe(11)
223+
})
224+
225+
it('add string long singular', () => {
226+
const a = dayjs({
227+
year: 2011,
228+
month: 9,
229+
date: 12,
230+
hour: 6,
231+
minute: 7,
232+
second: 8,
233+
millisecond: 500
234+
})
235+
236+
expect(a.add(50, 'milliseconds').millisecond()).toBe(550)
237+
expect(a.add(1, 'seconds').second()).toBe(9)
238+
expect(a.add(1, 'minutes').minute()).toBe(8)
239+
expect(a.add(1, 'hours').hour()).toBe(7)
240+
expect(a.add(1, 'days').date()).toBe(13)
241+
expect(a.add(1, 'weeks').date()).toBe(19)
242+
expect(a.add(1, 'months').month()).toBe(9)
243+
expect(a.add(1, 'years').year()).toBe(2012)
244+
expect(a.add(1, 'quarters').month()).toBe(11)
245+
})
246+
247+
it('add string short', () => {
248+
const a = dayjs({
249+
year: 2011,
250+
month: 9,
251+
date: 12,
252+
hour: 6,
253+
minute: 7,
254+
second: 8,
255+
millisecond: 500
256+
})
257+
258+
expect(a.add(50, 'ms').millisecond()).toBe(550)
259+
expect(a.add(1, 's').second()).toBe(9)
260+
expect(a.add(1, 'm').minute()).toBe(8)
261+
expect(a.add(1, 'h').hour()).toBe(7)
262+
expect(a.add(1, 'd').date()).toBe(13)
263+
expect(a.add(1, 'w').date()).toBe(19)
264+
expect(a.add(1, 'M').month()).toBe(9)
265+
expect(a.add(1, 'y').year()).toBe(2012)
266+
expect(a.add(1, 'Q').month()).toBe(11)
267+
})
268+
269+
it('add strings string short', () => {
270+
const a = dayjs({
271+
year: 2011,
272+
month: 9,
273+
date: 12,
274+
hour: 6,
275+
minute: 7,
276+
second: 8,
277+
millisecond: 500
278+
})
279+
280+
expect(a.add('50', 'ms').millisecond()).toBe(550)
281+
expect(a.add('1', 's').second()).toBe(9)
282+
expect(a.add('1', 'm').minute()).toBe(8)
283+
expect(a.add('1', 'h').hour()).toBe(7)
284+
expect(a.add('1', 'd').date()).toBe(13)
285+
expect(a.add('1', 'w').date()).toBe(19)
286+
expect(a.add('1', 'M').month()).toBe(9)
287+
expect(a.add('1', 'y').year()).toBe(2012)
288+
expect(a.add('1', 'Q').month()).toBe(11)
289+
})
290+
291+
it('add no string with milliseconds default', () => {
292+
const a = dayjs({
293+
year: 2011,
294+
month: 9,
295+
date: 12,
296+
hour: 6,
297+
minute: 7,
298+
second: 8,
299+
millisecond: 500
300+
})
301+
302+
expect(a.add(50).millisecond()).toBe(550)
303+
})
304+
305+
it('subtract strings string short', () => {
306+
const a = dayjs({
307+
year: 2011,
308+
month: 9,
309+
date: 12,
310+
hour: 6,
311+
minute: 7,
312+
second: 8,
313+
millisecond: 500
314+
})
315+
expect(a.subtract('50', 'ms').millisecond()).toBe(450)
316+
expect(a.subtract('1', 's').second()).toBe(7)
317+
expect(a.subtract('1', 'm').minute()).toBe(6)
318+
expect(a.subtract('1', 'h').hour()).toBe(5)
319+
expect(a.subtract('1', 'd').date()).toBe(11)
320+
expect(a.subtract('1', 'w').date()).toBe(5)
321+
expect(a.subtract('1', 'M').month()).toBe(7)
322+
expect(a.subtract('1', 'y').year()).toBe(2010)
323+
expect(a.subtract('1', 'Q').month()).toBe(5)
324+
})
325+
326+
it('add decimal values of days and months', () => {
327+
expect(dayjs([2016, 4, 3]).add(1.6, 'days').date()).toBe(5)
328+
expect(dayjs([2016, 4, 3]).add(-1.6, 'days').date()).toBe(1)
329+
expect(dayjs([2016, 4, 1]).add(-1.6, 'days').date()).toBe(30)
330+
expect(dayjs([2016, 4, 3]).add(1.6, 'months').month()).toBe(4)
331+
expect(dayjs([2016, 4, 3]).add(-1.6, 'months').month()).toBe(1)
332+
expect(dayjs([2016, 1, 3]).add(-1.6, 'months').month()).toBe(11)
333+
expect(dayjs([2016, 4, 3]).subtract(1.6, 'days').date()).toBe(1)
334+
expect(dayjs([2016, 4, 2]).subtract(1.6, 'days').date()).toBe(31)
335+
expect(dayjs([2016, 2, 1]).subtract(1.1, 'days').date()).toBe(31)
336+
expect(dayjs([2016, 4, 3]).subtract(-1.6, 'days').date()).toBe(5)
337+
expect(dayjs([2016, 4, 30]).subtract(-1.6, 'days').date()).toBe(2)
338+
expect(dayjs([2016, 4, 3]).subtract(1.6, 'months').month()).toBe(1)
339+
expect(dayjs([2016, 4, 3]).subtract(-1.6, 'months').month()).toBe(4)
340+
expect(dayjs([2016, 12, 31]).subtract(-1.6, 'months').month()).toBe(0)
341+
expect(dayjs([2016, 1, 1]).add(1.6, 'years').format('YYYY-MM-DD')).toBe('2017-01-01')
342+
expect(dayjs([2016, 7, 1]).add(1.6, 'years').format('YYYY-MM-DD')).toBe('2017-07-01')
343+
expect(dayjs([2016, 1, 1]).add(1.1, 'quarters').format('YYYY-MM-DD')).toBe('2016-04-01')
344+
})

‎types/plugin/objectSupport.d.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { PluginFunc } from 'dayjs'
2+
3+
declare const plugin: PluginFunc
4+
export = plugin
5+
6+
declare module 'dayjs' {
7+
interface Dayjs {
8+
set(argument: object): Dayjs
9+
add(argument: object): Dayjs
10+
subtract(argument: object): Dayjs
11+
}
12+
}

0 commit comments

Comments
 (0)
Please sign in to comment.