Skip to content

Commit

Permalink
feat(date): 新增 ms 获取毫秒值
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Nov 8, 2021
1 parent 8f0e27d commit ad6a6eb
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/date/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,5 +343,6 @@ export * from './anyToDate'
export * from './formatDate'
export * from './formatDistanceAgo'
export * from './intervalToRestrictiveDuration'
export * from './ms'
export * from './numeralDayToChineseDay'
// @endindex
74 changes: 74 additions & 0 deletions src/date/ms.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { ms } from './ms'

describe('ms', () => {
test('纯数字正常', () => {
expect(ms(1)).toBe(1)
expect(ms(2.5)).toBe(2.5)
expect(ms(100)).toBe(100)
})

test('纯字符串正常', () => {
expect(ms('1ms')).toBe(1)
expect(ms('1s')).toBe(1000)
expect(ms('5d')).toBe(5 * 24 * 60 * 60 * 1000)
})

test('数字+单位正常', () => {
expect(ms(1, 'ms')).toBe(1)
expect(ms(1, 's')).toBe(1000)
expect(ms(5, 'd')).toBe(5 * 24 * 60 * 60 * 1000)
})

test('返回秒正常', () => {
expect(ms('1s', true)).toBe(1)
expect(ms('5d', true)).toBe(5 * 24 * 60 * 60)
expect(ms(1, 's', true)).toBe(1)
expect(ms(5, 'd', true)).toBe(5 * 24 * 60 * 60)
})

test('非法值应报错', () => {
expect(function () {
// @ts-expect-error - We expect this to throw.
ms('')
}).toThrowError()
expect(function () {
// @ts-expect-error - We expect this to throw.
ms(undefined)
}).toThrowError()
expect(function () {
// @ts-expect-error - We expect this to throw.
ms(null)
}).toThrowError()
expect(function () {
// @ts-expect-error - We expect this to throw.
ms([])
}).toThrowError()
expect(function () {
// @ts-expect-error - We expect this to throw.
ms({})
}).toThrowError()
expect(function () {
ms(NaN)
}).toThrowError()
expect(function () {
ms(Infinity)
}).toThrowError()
expect(function () {
ms(-Infinity)
}).toThrowError()
expect(function () {
ms(
1,
// @ts-expect-error - We expect this to throw.
'mo',
)
}).toThrowError()
expect(function () {
ms(
1,
// @ts-expect-error - We expect this to throw.
{},
)
}).toThrowError()
})
})
83 changes: 83 additions & 0 deletions src/date/ms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// 参考: https://github.com/vercel/ms/blob/master/src/index.ts

const _ms = 1
const _s = _ms * 1000
const _m = _s * 60
const _h = _m * 60
const _d = _h * 24
const _w = _d * 7
const _y = _d * 365.25

export type MsUnit = 'y' | 'w' | 'd' | 'h' | 'm' | 's' | 'ms'
export type MsNumberValue = number
export type MsStringValue = `${number}${MsUnit}`
export type MsValue = MsNumberValue | MsStringValue

const unitToTimes: Record<MsUnit, number> = Object.create({
y: _y,
w: _w,
d: _d,
h: _h,
m: _m,
s: _s,
ms: _ms,
})

const re = /^(\d+)(y|w|d|h|m|s|ms)$/

/**
* 获取毫秒值。
*
* @param value 值
* @param unit 单位
* @param returnSeconds 是否返回秒值
*/
export function ms(value: number, unit: MsUnit, returnSeconds?: boolean): number
/**
* 获取毫秒值。
*
* @param value 值
* @param returnSeconds 是否返回秒值
*/
export function ms(value: MsValue, returnSeconds?: boolean): number
export function ms(
value: MsValue,
unit?: MsUnit | boolean,
returnSeconds?: boolean,
): number {
if (typeof unit === 'boolean') {
returnSeconds = unit
unit = undefined
}

let msValue!: number

if (typeof value === 'string' && value.length > 0) {
const match = re.exec(value)
if (!match) {
throw new TypeError(`value 值非法: value=${JSON.stringify(value)}`)
}
const v = parseFloat(match[1])
const u: MsUnit = match[2] as any
const t = unitToTimes[u]
msValue = v * t
} else if (typeof value === 'number' && isFinite(value)) {
if (unit != null) {
if (typeof unit === 'string') {
const t = unitToTimes[unit]
if (!t) {
throw new TypeError(`unit 值非法: unit=${JSON.stringify(unit)}`)
}
msValue = value * t
} else {
throw new TypeError('unit 必须是一个字符串')
}
} else {
msValue = value
}
} else {
throw new TypeError('value 必须是字符串或数字')
}

return returnSeconds ? Math.round(msValue / 1000) : msValue
}

0 comments on commit ad6a6eb

Please sign in to comment.