-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(date): 新增 intervalToRestrictiveDuration
- Loading branch information
Showing
4 changed files
with
270 additions
and
0 deletions.
There are no files selected for viewing
97 changes: 97 additions & 0 deletions
97
src/date/__snapshots__/intervalToRestrictiveDuration.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`intervalToRestrictiveDuration target 为 day 时表现正常 1`] = ` | ||
Object { | ||
"days": 367, | ||
"hours": 0, | ||
"milliseconds": 200, | ||
"minutes": 0, | ||
"months": 0, | ||
"seconds": 0, | ||
"years": 0, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration target 为 hour 时表现正常 1`] = ` | ||
Object { | ||
"days": 0, | ||
"hours": 8808, | ||
"milliseconds": 200, | ||
"minutes": 0, | ||
"months": 0, | ||
"seconds": 0, | ||
"years": 0, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration target 为 millisecond 时表现正常 1`] = ` | ||
Object { | ||
"days": 0, | ||
"hours": 0, | ||
"milliseconds": 31708800200, | ||
"minutes": 0, | ||
"months": 0, | ||
"seconds": 0, | ||
"years": 0, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration target 为 minute 时表现正常 1`] = ` | ||
Object { | ||
"days": 0, | ||
"hours": 0, | ||
"milliseconds": 200, | ||
"minutes": 528480, | ||
"months": 0, | ||
"seconds": 0, | ||
"years": 0, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration target 为 month 时表现正常 1`] = ` | ||
Object { | ||
"days": 2, | ||
"hours": 0, | ||
"milliseconds": 200, | ||
"minutes": 0, | ||
"months": 12, | ||
"seconds": 0, | ||
"years": 0, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration target 为 second 时表现正常 1`] = ` | ||
Object { | ||
"days": 0, | ||
"hours": 0, | ||
"milliseconds": 200, | ||
"minutes": 0, | ||
"months": 0, | ||
"seconds": 31708800, | ||
"years": 0, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration target 为 year 时表现正常 1`] = ` | ||
Object { | ||
"days": 2, | ||
"hours": 0, | ||
"milliseconds": 200, | ||
"minutes": 0, | ||
"months": 0, | ||
"seconds": 0, | ||
"years": 1, | ||
} | ||
`; | ||
|
||
exports[`intervalToRestrictiveDuration 未设置 target 时表现正常 1`] = ` | ||
Object { | ||
"days": 2, | ||
"hours": 0, | ||
"milliseconds": 200, | ||
"minutes": 0, | ||
"months": 0, | ||
"seconds": 0, | ||
"years": 1, | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { addDays, addMilliseconds, addYears } from 'date-fns/esm' | ||
import { intervalToRestrictiveDuration } from './intervalToRestrictiveDuration' | ||
|
||
describe('intervalToRestrictiveDuration', () => { | ||
const start = new Date(2020, 5 - 1, 21, 0, 0, 0, 0) | ||
const end = addYears(addMilliseconds(addDays(start, 2), 200), 1) | ||
|
||
test('未设置 target 时表现正常', () => { | ||
expect(intervalToRestrictiveDuration(start, end)).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 year 时表现正常', () => { | ||
expect(intervalToRestrictiveDuration(start, end, 'year')).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 month 时表现正常', () => { | ||
expect(intervalToRestrictiveDuration(start, end, 'month')).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 day 时表现正常', () => { | ||
expect(intervalToRestrictiveDuration(start, end, 'day')).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 hour 时表现正常', () => { | ||
expect(intervalToRestrictiveDuration(start, end, 'hour')).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 minute 时表现正常', () => { | ||
expect( | ||
intervalToRestrictiveDuration(start, end, 'minute'), | ||
).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 second 时表现正常', () => { | ||
expect( | ||
intervalToRestrictiveDuration(start, end, 'second'), | ||
).toMatchSnapshot() | ||
}) | ||
|
||
test('target 为 millisecond 时表现正常', () => { | ||
expect( | ||
intervalToRestrictiveDuration(start, end, 'millisecond'), | ||
).toMatchSnapshot() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { anyToDate } from './anyToDate' | ||
import { | ||
compareAsc, | ||
differenceInDays, | ||
differenceInHours, | ||
differenceInMilliseconds, | ||
differenceInMinutes, | ||
differenceInMonths, | ||
differenceInSeconds, | ||
differenceInYears, | ||
isValid, | ||
sub, | ||
} from 'date-fns/esm' | ||
|
||
export type IntervalToRestrictiveDurationTarget = | ||
| 'year' | ||
| 'month' | ||
| 'day' | ||
| 'hour' | ||
| 'minute' | ||
| 'second' | ||
| 'millisecond' | ||
|
||
export interface IntervalToRestrictiveDurationResult { | ||
years: number | ||
months: number | ||
days: number | ||
hours: number | ||
minutes: number | ||
seconds: number | ||
milliseconds: number | ||
} | ||
|
||
// ref: https://github.com/date-fns/date-fns/blob/master/src/intervalToDuration/index.js | ||
export function intervalToRestrictiveDuration( | ||
start: string | number | Date, | ||
end: string | number | Date, | ||
target: IntervalToRestrictiveDurationTarget = 'year', | ||
): IntervalToRestrictiveDurationResult { | ||
const dateLeft = anyToDate(start) | ||
const dateRight = anyToDate(end) | ||
|
||
if (!isValid(dateLeft)) { | ||
throw new RangeError('Start Date is invalid') | ||
} | ||
if (!isValid(dateRight)) { | ||
throw new RangeError('End Date is invalid') | ||
} | ||
|
||
const duration: IntervalToRestrictiveDurationResult = { | ||
years: 0, | ||
months: 0, | ||
days: 0, | ||
hours: 0, | ||
minutes: 0, | ||
seconds: 0, | ||
milliseconds: 0, | ||
} | ||
|
||
let remaining: Date = dateLeft | ||
|
||
const sign = compareAsc(dateLeft, dateRight) | ||
|
||
if (target === 'year') { | ||
duration.years = Math.abs(differenceInYears(remaining, dateRight)) | ||
} | ||
|
||
if (target === 'year' || target === 'month') { | ||
remaining = sub(remaining, { years: sign * duration.years }) | ||
duration.months = Math.abs(differenceInMonths(remaining, dateRight)) | ||
} | ||
|
||
if (target === 'year' || target === 'month' || target === 'day') { | ||
remaining = sub(remaining, { months: sign * duration.months }) | ||
duration.days = Math.abs(differenceInDays(remaining, dateRight)) | ||
} | ||
|
||
if ( | ||
target === 'year' || | ||
target === 'month' || | ||
target === 'day' || | ||
target === 'hour' | ||
) { | ||
remaining = sub(remaining, { days: sign * duration.days }) | ||
duration.hours = Math.abs(differenceInHours(remaining, dateRight)) | ||
} | ||
|
||
if ( | ||
target === 'year' || | ||
target === 'month' || | ||
target === 'day' || | ||
target === 'hour' || | ||
target === 'minute' | ||
) { | ||
remaining = sub(remaining, { hours: sign * duration.hours }) | ||
duration.minutes = Math.abs(differenceInMinutes(remaining, dateRight)) | ||
} | ||
|
||
if ( | ||
target === 'year' || | ||
target === 'month' || | ||
target === 'day' || | ||
target === 'hour' || | ||
target === 'minute' || | ||
target === 'second' | ||
) { | ||
remaining = sub(remaining, { minutes: sign * duration.minutes }) | ||
duration.seconds = Math.abs(differenceInSeconds(remaining, dateRight)) | ||
} | ||
|
||
if ( | ||
target === 'year' || | ||
target === 'month' || | ||
target === 'day' || | ||
target === 'hour' || | ||
target === 'minute' || | ||
target === 'second' || | ||
target === 'millisecond' | ||
) { | ||
remaining = sub(remaining, { seconds: sign * duration.seconds }) | ||
duration.milliseconds = Math.abs( | ||
differenceInMilliseconds(remaining, dateRight), | ||
) | ||
} | ||
|
||
return duration | ||
} |