diff --git a/lib/datetime/computeAge.js b/lib/datetime/computeAge.js new file mode 100644 index 0000000..887d22b --- /dev/null +++ b/lib/datetime/computeAge.js @@ -0,0 +1,33 @@ +import { parseISO, isValid, differenceInYears, isBefore } from 'date-fns'; + +/** + * 计算年龄 + * + * @author 卞雪瑞 + * @category 时间操作 + * @alias yd_compute_age + * @param {String} birthday - 生日日期字符串 + * @summary 根据给的生日计算出用户的年龄 + * @returns {Number} - 返回计算出的年龄,如果未提供生日则返回0 + */ +const computeAge = (birthday) => { + if (birthday) { + const _birthday = parseISO(birthday); + + if (!isValid(_birthday)) { + return 0; + } + + const cur = new Date(); + let age = differenceInYears(cur, _birthday); + + if (isBefore(cur, new Date(cur.getFullYear(), _birthday.getMonth(), _birthday.getDate()))) { + age--; + } + + return age; + } + return 0; +}; + +export default computeAge; diff --git a/lib/datetime/computeAge.test.js b/lib/datetime/computeAge.test.js new file mode 100644 index 0000000..623f7c3 --- /dev/null +++ b/lib/datetime/computeAge.test.js @@ -0,0 +1,36 @@ +import { describe, test, expect } from 'vitest'; +import { format, parseISO, getYear, subMonths } from 'date-fns'; +import dy_compute_age from './computeAge'; // 确保路径正确 + +describe('dy_compute_age', () => { + test('正确计算年龄', () => { + const birthday = '1990-01-01'; // 例如,出生日期为 1990 年 1 月 1 日 + const expectedAge = new Date().getFullYear() - 1990; // 计算预期的年龄 + const age = dy_compute_age(birthday); + expect(age).toBe(expectedAge); + }); + + test('计算同一天出生的年龄应为 0', () => { + const today = format(new Date(), 'yyyy-MM-dd'); + const age = dy_compute_age(today); + expect(age).toBe(0); + }); + + test('边界情况:出生日期在今年的某一天', () => { + const birthday = format(subMonths(new Date(), 5), 'yyyy-MM-dd'); // 例如,5 个月前 + const expectedAge = getYear(new Date()) - getYear(parseISO(birthday)); + const age = dy_compute_age(birthday); + expect(age).toBe(expectedAge); + }); + + test('无效日期应返回 0', () => { + const invalidDate = 'not-a-date'; + const age = dy_compute_age(invalidDate); + expect(age).toBe(0); + }); + + test('未提供出生日期应返回 0', () => { + const age = dy_compute_age(); + expect(age).toBe(0); + }); +}); diff --git a/lib/datetime/dateRange.js b/lib/datetime/dateRange.js new file mode 100644 index 0000000..bdeb9ab --- /dev/null +++ b/lib/datetime/dateRange.js @@ -0,0 +1,29 @@ +import { add, isBefore } from 'date-fns'; + +/** + * 返回一个时间范围 + * @category 时间操作 + * @alias yd_date_range + * @param {number} year - 需要增加的年数,默认为0 + * @param {number} month - 需要增加的月数,默认为0 + * @param {number} day - 需要增加的天数,默认为0 + * @param {number} hour - 需要增加的小时数,默认为0 + * @param {number} minute - 需要增加的分钟数,默认为0 + * @param {number} second - 需要增加的秒数,默认为0 + * @summary 生成一个时间范围数组,该数组包含当前时间和目标时间 + * 如果目标时间在当前时间之后,则返回 [当前时间, 目标时间] 的数组 + * 如果目标时间在当前时间之前或相同,则返回 [目标时间, 当前时间] 的数组 + * @returns {Array} 返回一个包含两个Date对象的数组,分别代表开始时间和结束时间 + */ + +const dateRange = (year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0) => { + const now = new Date(); + const targetDate = add(now, { years: year, months: month, days: day, hours: hour, minutes: minute, seconds: second }); + + if (isBefore(now, targetDate)) { + return [now, targetDate]; + } + return [targetDate, now]; +}; + +export default dateRange; diff --git a/lib/datetime/dateRange.test.js b/lib/datetime/dateRange.test.js new file mode 100644 index 0000000..4f71744 --- /dev/null +++ b/lib/datetime/dateRange.test.js @@ -0,0 +1,47 @@ +import { describe, test, expect } from 'vitest'; +import { add, isEqual, isBefore, startOfSecond } from 'date-fns'; +import yd_date_range from './dateRange'; + +describe('yd_date_range', () => { + test('默认情况下返回当前时间范围', () => { + const [start, end] = yd_date_range(); + const now = new Date(); + expect(isEqual(startOfSecond(start), startOfSecond(now))).toBe(true); + expect(isEqual(startOfSecond(end), startOfSecond(now))).toBe(true); + }); + + test('增加一年', () => { + const [start, end] = yd_date_range(1); + expect(end.getFullYear()).toBe(start.getFullYear() + 1); + }); + + test('增加一个月', () => { + const [start, end] = yd_date_range(0, 1); + expect((end.getMonth() + 12) % 12).toBe((start.getMonth() + 1) % 12); + }); + + test('增加一天', () => { + const [start, end] = yd_date_range(0, 0, 1); + expect(end.getDate()).toBe(start.getDate() + 1); + }); + + test('增加一小时', () => { + const [start, end] = yd_date_range(0, 0, 0, 1); + expect((end.getHours() + 24) % 24).toBe((start.getHours() + 1) % 24); + }); + + test('增加一分钟', () => { + const [start, end] = yd_date_range(0, 0, 0, 0, 1); + expect((end.getMinutes() + 60) % 60).toBe((start.getMinutes() + 1) % 60); + }); + + test('增加一秒钟', () => { + const [start, end] = yd_date_range(0, 0, 0, 0, 0, 1); + expect((end.getSeconds() + 60) % 60).toBe((start.getSeconds() + 1) % 60); + }); + + test('如果目标日期在当前日期之前,返回的顺序应调整', () => { + const [start, end] = yd_date_range(-1); // 减少一年 + expect(isBefore(start, end)).toBe(true); + }); +});