Skip to content

Commit c1beb5f

Browse files
authored
Merge pull request #23 from xx45/dev
fix(add endof): add endOf && add startOf day
2 parents cfb0c03 + 3a569ce commit c1beb5f

File tree

7 files changed

+224
-48
lines changed

7 files changed

+224
-48
lines changed

.eslintrc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
"jest/globals": true
88
},
99
"rules": {
10-
"semi": [2, "never"]
10+
"semi": [
11+
2,
12+
"never"
13+
],
14+
"comma-dangle": [
15+
"error",
16+
"never"
17+
]
1118
}
1219
}

src/constant.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@ export const SECONDS_A_MINUTE = 60
22
export const SECONDS_A_HOUR = SECONDS_A_MINUTE * 60
33
export const SECONDS_A_DAY = SECONDS_A_HOUR * 24
44
export const SECONDS_A_WEEK = SECONDS_A_DAY * 7
5+
6+
export const MILLISECONDS_A_SECOND = 1000
7+
export const MILLISECONDS_A_MINUTE = SECONDS_A_MINUTE * MILLISECONDS_A_SECOND
8+
export const MILLISECONDS_A_HOUR = SECONDS_A_HOUR * MILLISECONDS_A_SECOND
9+
export const MILLISECONDS_A_DAY = SECONDS_A_DAY * MILLISECONDS_A_SECOND
10+
export const MILLISECONDS_A_WEEK = SECONDS_A_WEEK * MILLISECONDS_A_SECOND

src/index.js

Lines changed: 101 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Dayjs {
3030
this.$hour = this.$date.getHours()
3131
this.$minute = this.$date.getMinutes()
3232
this.$second = this.$date.getSeconds()
33+
this.$milliseconds = this.$date.getMilliseconds()
3334
}
3435

3536
year() {
@@ -44,6 +45,22 @@ class Dayjs {
4445
return this.$day
4546
}
4647

48+
hour() {
49+
return this.$hour
50+
}
51+
52+
minute() {
53+
return this.$minute
54+
}
55+
56+
second() {
57+
return this.$second
58+
}
59+
60+
millisecond() {
61+
return this.$milliseconds
62+
}
63+
4764
unix() {
4865
return Math.floor(this.valueOf() / 1000)
4966
}
@@ -53,21 +70,32 @@ class Dayjs {
5370
return this.$date.getTime()
5471
}
5572

56-
toString() {
57-
return this.$date.toUTCString()
58-
}
59-
60-
startOf(arg) {
73+
startOf(arg, isStartOf = true) {
6174
switch (arg) {
6275
case 'year':
63-
return new Dayjs(new Date(this.year(), 0, 1))
76+
if (isStartOf) {
77+
return new Dayjs(new Date(this.year(), 0, 1))
78+
}
79+
return new Dayjs(new Date(this.year(), 11, 31)).endOf('day')
6480
case 'month':
65-
return new Dayjs(new Date(this.year(), this.month(), 1))
81+
if (isStartOf) {
82+
return new Dayjs(new Date(this.year(), this.month(), 1))
83+
}
84+
return new Dayjs(new Date(this.year(), this.month() + 1, 0)).endOf('day')
85+
case 'day':
86+
if (isStartOf) {
87+
return new Dayjs(this.toDate().setHours(0, 0, 0, 0))
88+
}
89+
return new Dayjs(this.toDate().setHours(23, 59, 59, 999))
6690
default:
67-
return this
91+
return this.clone()
6892
}
6993
}
7094

95+
endOf(arg) {
96+
return this.startOf(arg, false)
97+
}
98+
7199
set(string, int) {
72100
if (!Utils.isNumber(int)) return this
73101
switch (string) {
@@ -99,25 +127,25 @@ class Dayjs {
99127
switch (string) {
100128
case 'm':
101129
case 'minutes':
102-
step = Constant.SECONDS_A_MINUTE
130+
step = Constant.MILLISECONDS_A_MINUTE
103131
break
104132
case 'h':
105133
case 'hours':
106-
step = Constant.SECONDS_A_HOUR
134+
step = Constant.MILLISECONDS_A_HOUR
107135
break
108136
case 'd':
109137
case 'days':
110-
step = Constant.SECONDS_A_DAY
138+
step = Constant.MILLISECONDS_A_DAY
111139
break
112140
case 'w':
113141
case 'weeks':
114-
step = Constant.SECONDS_A_WEEK
142+
step = Constant.MILLISECONDS_A_WEEK
115143
break
116144
default: // s seconds
117-
step = 1
145+
step = Constant.MILLISECONDS_A_SECOND
118146
}
119-
const nextTimeStamp = this.unix() + (number * step)
120-
return new Dayjs(nextTimeStamp * 1000)
147+
const nextTimeStamp = this.valueOf() + (number * step)
148+
return new Dayjs(nextTimeStamp)
121149
}
122150

123151
subtract(number, string) {
@@ -165,13 +193,36 @@ class Dayjs {
165193
})
166194
}
167195

168-
diff(otherDate) {
196+
diff(otherDate, unit, float = false) {
169197
const other = otherDate instanceof Dayjs ? otherDate : new Dayjs(otherDate)
170-
return this.valueOf() - other.valueOf()
198+
const diff = this - other
199+
let result = Utils.monthDiff(this, other)
200+
switch (unit) {
201+
case 'years':
202+
result /= 12
203+
break
204+
case 'months':
205+
break
206+
case 'quarters':
207+
result /= 3
208+
break
209+
case 'weeks':
210+
result = diff / Constant.MILLISECONDS_A_WEEK
211+
break
212+
case 'days':
213+
result = diff / Constant.MILLISECONDS_A_DAY
214+
break
215+
case 'seconds':
216+
result = diff / Constant.MILLISECONDS_A_SECOND
217+
break
218+
default: // milliseconds
219+
result = diff
220+
}
221+
return float ? result : Utils.absFloor(result)
171222
}
172223

173224
daysInMonth() {
174-
return new Dayjs(new Date(this.year(), this.month() + 1, 0)).date()
225+
return this.endOf('month').date()
175226
}
176227

177228
clone() {
@@ -182,9 +233,41 @@ class Dayjs {
182233
return new Date(this.$date)
183234
}
184235

236+
toArray() {
237+
return [
238+
this.year(),
239+
this.month(),
240+
this.date(),
241+
this.hour(),
242+
this.minute(),
243+
this.second(),
244+
this.millisecond()
245+
]
246+
}
247+
248+
toJSON() {
249+
return this.toISOString()
250+
}
251+
185252
toISOString() {
186253
return this.toDate().toISOString()
187254
}
255+
256+
toObject() {
257+
return {
258+
years: this.year(),
259+
months: this.month(),
260+
date: this.date(),
261+
hours: this.hour(),
262+
minutes: this.minute(),
263+
seconds: this.second(),
264+
milliseconds: this.millisecond()
265+
}
266+
}
267+
268+
toString() {
269+
return this.$date.toUTCString()
270+
}
188271
}
189272

190273
export default config => (new Dayjs(config))

src/utils.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,21 @@ export const padStart = (string, length, pad) => {
55

66
export const isNumber = n => (!Number.isNaN(parseFloat(n)) && Number.isFinite(n))
77

8+
export const monthDiff = (a, b) => {
9+
// function from moment.js monthDiff
10+
const wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month())
11+
const anchor = a.clone().add(wholeMonthDiff, 'months')
12+
let anchor2
13+
let adjust
14+
if (b - anchor < 0) {
15+
anchor2 = a.clone().add(wholeMonthDiff - 1, 'months')
16+
adjust = (b - anchor) / (anchor - anchor2)
17+
} else {
18+
anchor2 = a.clone().add(wholeMonthDiff + 1, 'months')
19+
adjust = (b - anchor) / (anchor2 - anchor)
20+
}
21+
return Number(-(wholeMonthDiff + adjust)) || 0
22+
}
23+
24+
export const absFloor = n => (n < 0 ? Math.ceil(n) || 0 : Math.floor(n))
25+

test/display.test.js

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,56 @@ it('Format Complex with other string - : / ', () => {
5959
expect(dayjs().format(string)).toBe(moment().format(string))
6060
})
6161

62-
it('Difference', () => {
63-
const dateString = '20110101'
64-
65-
const dayjsA = dayjs()
66-
const dayjsB = dayjs(dateString)
67-
68-
const momentA = moment()
69-
const momentB = moment(dateString)
70-
expect(dayjsA.diff(dayjsB)).toBe(momentA.diff(momentB))
62+
describe('Difference', () => {
63+
it('empty -> default milliseconds', () => {
64+
const dateString = '20110101'
65+
const dayjsA = dayjs()
66+
const dayjsB = dayjs(dateString)
67+
const momentA = moment()
68+
const momentB = moment(dateString)
69+
expect(dayjsA.diff(dayjsB)).toBe(momentA.diff(momentB))
70+
})
71+
72+
it('diff -> none dayjs object', () => {
73+
const dateString = '2013-02-08'
74+
const dayjsA = dayjs()
75+
const dayjsB = new Date(dateString)
76+
const momentA = moment()
77+
const momentB = new Date(dateString)
78+
expect(dayjsA.diff(dayjsB)).toBe(momentA.diff(momentB))
79+
})
80+
81+
it('diff -> in seconds, days, weeks, months, quarters, years ', () => {
82+
const dayjsA = dayjs()
83+
const dayjsB = dayjs().add(1000, 'days')
84+
const dayjsC = dayjs().subtract(1000, 'days')
85+
const momentA = moment()
86+
const momentB = moment().add(1000, 'days')
87+
const momentC = moment().subtract(1000, 'days')
88+
const units = ['seconds', 'days', 'weeks', 'months', 'quarters', 'years']
89+
units.forEach((unit) => {
90+
expect(dayjsA.diff(dayjsB, unit)).toBe(momentA.diff(momentB, unit))
91+
expect(dayjsA.diff(dayjsB, unit, true)).toBe(momentA.diff(momentB, unit, true))
92+
expect(dayjsA.diff(dayjsC, unit)).toBe(momentA.diff(momentC, unit))
93+
expect(dayjsA.diff(dayjsC, unit, true)).toBe(momentA.diff(momentC, unit, true))
94+
})
95+
})
96+
97+
it('Special diff in month according to moment.js', () => {
98+
const dayjsA = dayjs('20160115')
99+
const dayjsB = dayjs('20160215')
100+
const dayjsC = dayjs('20170115')
101+
const momentA = moment('20160115')
102+
const momentB = moment('20160215')
103+
const momentC = moment('20170115')
104+
const units = ['months', 'quarters', 'years']
105+
units.forEach((unit) => {
106+
expect(dayjsA.diff(dayjsB, unit)).toBe(momentA.diff(momentB, unit))
107+
expect(dayjsA.diff(dayjsB, unit, true)).toBe(momentA.diff(momentB, unit, true))
108+
expect(dayjsA.diff(dayjsC, unit)).toBe(momentA.diff(momentC, unit))
109+
expect(dayjsA.diff(dayjsC, unit, true)).toBe(momentA.diff(momentC, unit, true))
110+
})
111+
})
71112
})
72113

73114
it('Unix Timestamp (milliseconds)', () => {
@@ -80,9 +121,10 @@ it('Unix Timestamp (seconds)', () => {
80121

81122
it('Days in Month', () => {
82123
expect(dayjs().daysInMonth()).toBe(moment().daysInMonth())
124+
expect(dayjs('20140201').daysInMonth()).toBe(moment('20140201').daysInMonth())
83125
})
84126

85-
it('As Javascript Date', () => {
127+
it('As Javascript Date -> toDate', () => {
86128
const base = dayjs()
87129
const momentBase = moment()
88130
const jsDate = base.toDate()
@@ -93,7 +135,18 @@ it('As Javascript Date', () => {
93135
expect(jsDate.toUTCString()).not.toBe(base.toString())
94136
})
95137

96-
it('As ISO 8601 String e.g. 2013-02-04T22:44:30.652Z', () => {
138+
it('As Array -> toArray', () => {
139+
expect(dayjs().toArray()).toEqual(moment().toArray())
140+
})
141+
142+
it('As JSON -> toJSON', () => {
143+
expect(dayjs().toJSON()).toBe(moment().toJSON())
144+
})
145+
146+
it('As ISO 8601 String -> toISOString e.g. 2013-02-04T22:44:30.652Z', () => {
97147
expect(dayjs().toISOString()).toBe(moment().toISOString())
98148
})
99149

150+
it('As Object -> toObject', () => {
151+
expect(dayjs().toObject()).toEqual(moment().toObject())
152+
})

test/manipulate.test.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@ afterEach(() => {
1010
MockDate.reset()
1111
})
1212

13-
it('StartOf Year', () => {
13+
it('StartOf EndOf Year', () => {
1414
expect(dayjs().startOf('year').unix()).toBe(moment().startOf('year').unix())
15+
expect(dayjs().endOf('year').unix()).toBe(moment().endOf('year').unix())
1516
})
1617

17-
it('StartOf Month', () => {
18+
it('StartOf EndOf Month', () => {
1819
expect(dayjs().startOf('month').unix()).toBe(moment().startOf('month').unix())
20+
expect(dayjs().endOf('month').unix()).toBe(moment().endOf('month').unix())
1921
})
2022

21-
it('StartOf Other', () => {
23+
it('StartOf EndOf Day', () => {
24+
expect(dayjs().startOf('day').unix()).toBe(moment().startOf('day').unix())
25+
expect(dayjs().endOf('day').unix()).toBe(moment().endOf('day').unix())
26+
})
27+
28+
it('StartOf EndOf Other -> no change', () => {
2229
expect(dayjs().startOf('otherString').unix()).toBe(moment().startOf('otherString').unix())
30+
expect(dayjs().endOf('otherString').unix()).toBe(moment().endOf('otherString').unix())
2331
})
2432

2533
it('Add Time days', () => {

0 commit comments

Comments
 (0)