API 参考
功能分类总览
全部 API 按功能分为五组,均为纯函数、非法入参不抛错、sideEffects: false 可 tree-shaking:
| 分类 | API | 一句话说明 |
|---|---|---|
| 格式化 | format | 旧版调用约定(偏移字符串 + 模板),完全兼容 |
formatDate | 格式化任意日期(字符串或 Date,不限"今天 ± N 天") | |
| 解析与校验 | parseDate | 日期字符串 → Date(iOS Safari 兼容 + 回写校验) |
isValid | 输入是否为可解析的合法日期 | |
| 相对时间与差值 | fromNow | '3 分钟前' / '2 天后' 中文相对时间 |
diff | 两日期差值 a - b,支持 7 种单位 | |
| 日期比较 | isToday / isSameDay | 日粒度判断(忽略时分秒) |
isBefore / isAfter | 时刻粒度比较(精确到毫秒) | |
| 年月信息 | getDays | 指定年月的天数(28/29/30/31) |
getYearofDays | 指定年份总天数(365/366) | |
getYearLastDays | 今年剩余天数(不含今天) | |
isLeapYear | 是否闰年 | |
| 调用方式 | datefmt | 冻结命名空间(只导入一个标识符) |
DateFmt / datefmt.create | 不可变链式建造者(Builder 模式) |
所有函数既可具名导出调用,也可通过 datefmt 命名空间调用(如 datefmt.formatDate),行为完全一致。
一、格式化
format(a?, b?)
格式化日期时间,完全兼容旧工具调用约定。
| 参数 | 类型 | 说明 |
|---|---|---|
a | string(可选) | 偏移字符串或格式化模板 |
b | string(可选) | 格式化模板(与 a 同时传入时,a 只按偏移解析) |
返回:格式化后的字符串。
调用形式:
| 调用 | 语义 |
|---|---|
format() | 当前时间,默认模板 'YYYY-MM-DD hh:ii:ss' |
format(pattern) | 当前时间按模板格式化 |
format(offset, pattern) | 相对今天偏移 N 天后按模板格式化 |
偏移字符串规则:/^\s*[+-]?\d+\s*$/,如 '-7'、'0'、'+3'、' -7 '; 仅平移日期、保留当天时分秒。非法输入不抛错:无法识别的参数按模板处理。
formatDate(input?, pattern?)
格式化任意日期。format 的基准恒为"今天",想格式化一个用户给定的日期(如后端返回值、生日)用 formatDate:
import { formatDate } from '@iefe/dateformat'
formatDate('2024-02-29') // '2024-02-29 00:00:00'(默认模板)
formatDate('2024/02/15 10:30:00', 'MM-DD hh:ii') // '02-15 10:30'
formatDate(new Date(), 'Y年M月D日') // 中文大写同样可用
formatDate('2023-03-10', '[第]Q季度 DDD') // '第1季度 069'(扩展 Token 同样可用)| 参数 | 类型 | 说明 |
|---|---|---|
input | string | Date(可选) | 待格式化的日期,解析规则同 parseDate |
pattern | string(可选) | 格式化模板,默认 'YYYY-MM-DD hh:ii:ss'(与 format 一致) |
返回:格式化后的字符串。
- 非法入参回退当前时间而非抛错(
formatDate('abc')→ 当前时间,与getDays回退本月同约定); - 偏移能力留给
format/ 建造者——formatDate('-7', 'YYYY-MM-DD')中'-7'不是合法日期,同样回退当前时间。
二、解析与校验
parseDate(input?)
解析日期字符串为 Date 对象(把库内 iOS 兼容的解析能力公开)。
不依赖 new Date(string) 原生解析,而是用正则取出年月日时分秒后以组件形式构造, 从根上规避 iOS Safari 上 new Date('2024-01-01 12:00:00') 返回 Invalid Date 的问题; 并带回写校验:'2023-02-31' 这类会溢出为 3 月的输入直接判非法。
| 参数 | 类型 | 说明 |
|---|---|---|
input | string | Date(可选) | 日期字符串或 Date 对象 |
返回:合法日期返回 Date(传 Date 时返回同一时刻的副本);非法输入返回 null(不抛错)。
支持的字符串格式(日期与时间之间的分隔符 - / / 前后需一致):
'YYYY-MM'、'YYYY/MM''YYYY-MM-DD'、'YYYY/MM/DD'- 上述任意格式带时间部分:
'2024-01-01 12:00'、'2024-01-01T12:00:00'等
parseDate('2024-02-15') // 2024 年 2 月 15 日 0 点的 Date
parseDate('2024-01-01 12:00:00') // iOS Safari 下同样可用
parseDate('2024/2/5') // 斜杠、不补零的月日均可
parseDate('2023-02-31') // null(回写校验:2 月没有 31 日)
parseDate('abc') // nullisValid(input?)
判断输入是否为可解析的合法日期,parseDate 的布尔便捷形式,适合表单校验等场景。
| 参数 | 类型 | 说明 |
|---|---|---|
input | string | Date(可选) | 日期字符串或 Date 对象 |
返回:可解析返回 true;null / undefined / 非法字符串 / Invalid Date 返回 false。
isValid('2024-02-29') // true
isValid('2023-02-29') // false(平年 2 月无 29 日)
isValid(new Date('x')) // false(Invalid Date)
isValid(undefined) // false三、相对时间与差值
fromNow(input?, baseDate?)
相对时间描述(中文口语):'刚刚'、'3 分钟前'、'2 天后'、'5 个月前'、'1 年前'。
| 参数 | 类型 | 说明 |
|---|---|---|
input | string | Date(可选) | 目标日期,解析规则同 parseDate |
返回:中文相对时间描述;非法或缺失输入返回空字符串(无法给出有意义的相对描述,不抛错、不误报"刚刚")。
阈值规则(按已过去的时长就近取档,月/年为 30 / 365 天的近似换算):
| 距今 | 输出 |
|---|---|
| < 1 分钟 | '刚刚'(过去/未来同文案) |
| < 1 小时 | 'N 分钟前' / 'N 分钟后' |
| < 1 天 | 'N 小时前' / 'N 小时后' |
| < 30 天 | 'N 天前' / 'N 天后' |
| < 12 个月(≈ 365 天) | 'N 个月前' / 'N 个月后' |
| 更久 | 'N 年前' / 'N 年后' |
// 假设当前时间 2023-03-10 15:00:00
fromNow(new Date()) // '刚刚'
fromNow('2023-03-10 14:30') // '30 分钟前'
fromNow('2023-03-11 14:00') // '23 小时后'
fromNow('2022-04-10 15:00') // '11 个月前'
fromNow('2013-03-10 15:00') // '10 年前'
fromNow('abc') // ''diff(a?, b?, unit?)
计算两个日期的差值 a - b(按指定单位,向零取整,负数表示 a 早于 b)。
| 参数 | 类型 | 说明 |
|---|---|---|
a | string | Date(可选) | 被减数日期 |
b | string | Date(可选) | 减数日期 |
unit | DiffUnit(可选) | 差值单位,默认 'day' |
返回:差值数值(a - b,向零取整)。
单位语义:
'ms'/'second'/'minute'/'hour'/'day':精确时间差换算后向零取整 (如相差 1.5 小时按'hour'得1;跨零点但不足 24 小时按'day'得0,与 dayjs 一致);'month'/'year':日历差值,只统计满整月 / 整周年的部分 (月末按钳制规则,2024-01-31→2024-02-29算满 1 个月,→2024-02-28不算)。
非法入参不抛错:a / b 缺失或无法解析时回退为当前时间,如 diff('abc') → 0。
diff('2024-03-01', '2024-01-01') // 60(默认单位 day)
diff('2024-01-01', '2024-03-01') // -60(顺序反过来得负数)
diff('2024-03-01 12:00', '2024-03-01 10:30', 'hour') // 1(1.5 小时向零取整)
diff('2024-03-01', '2024-01-01', 'month') // 2
diff('2024-02-29', '2024-01-31', 'month') // 1(月末钳制算满月)
diff('2024-03-10', '2000-03-15', 'year') // 23(只统计满整周年)四、日期比较
四个判定函数的统一约定:非法或缺失输入一律返回 false,不做"回退当前时间" (回退会让 isSameDay('abc', today) 在今天恰好命中时误报 true;值类函数 format / getDays 等仍保持回退约定)。
isToday(input?, baseDate?)
判断给定日期是否是今天(日粒度,忽略时分秒)。
// 假设今天是 2023-03-10
isToday('2023-03-10 23:59') // true(同一天即可)
isToday('2023-03-11') // false
isToday('abc') // falseisSameDay(a?, b?)
判断两个日期是否为同一天(日粒度,忽略时分秒)。
isSameDay('2023-03-10 08:00', '2023-03-10 23:59') // true
isSameDay('2023-03-10', '2023-03-11') // false
isSameDay('abc', '2023-03-10') // falseisBefore(a?, b?)
判断 a 是否早于 b(时刻粒度,精确到毫秒;相等返回 false)。
isBefore('2023-03-10 08:00', '2023-03-10 09:00') // true(时刻粒度)
isBefore('2023-03-10', '2023-03-10') // false(相等不算早于)isAfter(a?, b?)
判断 a 是否晚于 b(时刻粒度,精确到毫秒;相等返回 false)。
isAfter('2023-03-11', '2023-03-10') // true
isAfter('2023-03-10', '2023-03-10') // false(相等不算晚于)五、年月信息
| 函数 | 参数 | 返回 | 说明 |
|---|---|---|---|
getYearLastDays() | 无 | number | 今年剩余天数(不含今天;今天 12-31 时返回 0) |
getYearofDays(year?) | number | string | number | 指定年份总天数(闰年 366,平年 365);省略或非法时回退今年 |
getDays(date?) | string | Date | number | 指定年月的天数;支持 'YYYY-MM'、'YYYY-MM-DD' 及斜杠变体与 Date,只取年月;省略或非法时回退本月 |
isLeapYear(year?) | number | string | boolean | 是否闰年;省略或非法时回退今年 |
四个方法均不抛错:无参时一律以"今天"为基准;非法入参回退默认值。
getYearLastDays()
今年剩余天数(不含今天)。即"今年 12 月 31 日零点"与"今天零点"的日序号差:
// 假设今天是 2023-03-10
getYearLastDays() // 296
getYearofDays() - getYearLastDays() // 69(今年已过去)getYearofDays(year?)
指定年份的总天数(365 / 366)。year 支持 number(如 2024)或纯数字字符串(如 '2024'):
// 假设今年是 2023
getYearofDays() // 365
getYearofDays('2022') // 365
getYearofDays(2024) // 366
getYearofDays('abc') // 365(回退今年,不抛错)getDays(date?)
指定日期所在月份的天数(28 / 29 / 30 / 31)。date 支持 'YYYY-MM'、'YYYY-MM-DD'、'YYYY/MM'、'YYYY/MM/DD' 与 Date 对象,只取年月、忽略日部分:
// 假设本月是 2023-03
getDays() // 31(本月)
getDays('2023-02') // 28
getDays('2024-02-15') // 29(只取年月)
getDays('2023/02') // 28(斜杠兼容)
getDays('abc') // 31(回退本月,不抛错)isLeapYear(year?)
判断指定年份是否为闰年(2 月有 29 天 / 全年 366 天)。规则:能被 4 整除且不能被 100 整除,或能被 400 整除(2000 闰、1900 平):
isLeapYear(2024) // true
isLeapYear(2023) // false
isLeapYear('2000') // true(被 400 整除)
isLeapYear(1900) // false(被 100 整除但不被 400 整除)datefmt 命名空间(Facade)
import { datefmt } from '@iefe/dateformat'上文五组功能的所有函数都收拢在 datefmt 上,与具名导出同源同行为:
| 成员 | 说明 |
|---|---|
datefmt.format(a?, b?) | 同 format |
datefmt.formatDate(input?, pattern?) | 同 formatDate |
datefmt.parseDate(input?) | 同 parseDate |
datefmt.isValid(input?) | 同 isValid |
datefmt.fromNow(input?) | 同 fromNow |
datefmt.diff(a?, b?, unit?) | 同 diff |
datefmt.isToday(input?) | 同 isToday |
datefmt.isSameDay(a?, b?) | 同 isSameDay |
datefmt.isBefore(a?, b?) | 同 isBefore |
datefmt.isAfter(a?, b?) | 同 isAfter |
datefmt.getDays(date?) | 同 getDays |
datefmt.getYearofDays(year?) | 同 getYearofDays |
datefmt.getYearLastDays() | 同 getYearLastDays |
datefmt.isLeapYear(year?) | 同 isLeapYear |
datefmt.create(pattern?) | 创建不可变建造者 DateFmt |
datefmt.format('-7', 'YYYY-MM-DD') // '2023-03-03'
datefmt.formatDate('2024-02-29') // '2024-02-29 00:00:00'
datefmt.fromNow('2023-03-10 14:30') // '30 分钟前'
datefmt.getDays('2024-02') // 29datefmt 经 Object.freeze 冻结:运行时(ESM 恒为严格模式)改写任何属性都会抛 TypeError,杜绝被下游挂载/篡改。
DateFmt 建造者(Builder)
不可变实现:所有配置存于私有快照,链式方法每步返回新实例,实例间无状态串扰。
declare class DateFmt {
static create(pattern?: string): DateFmt
pattern(pattern: string): DateFmt
offset(days: number | string): DateFmt
base(date?: Date): DateFmt
render(): string
toString(): string
}| 方法 | 说明 |
|---|---|
DateFmt.create(pattern?) | 工厂方法;pattern 默认 'YYYY-MM-DD hh:ii:ss' |
.pattern(pattern) | 换模板,返回新实例 |
.offset(days) | 偏移天数(可叠加:.offset(-7).offset('+3') 净偏移 -4);仅平移日期、保留时分秒;非法参数忽略不抛错 |
.base(date?) | 注入基准时间(便于测试固定时间);非法值回退当前时间 |
.render() | 产出字符串;延迟求值,调用时才读系统时间 |
.toString() | render() 的别名,可用于模板字符串 `${builder}` |
// 假设当前时间 2023-03-10 15:00:00
datefmt.create('YYYY-MM-DD hh:ii:ss').offset(-7).render()
// '2023-03-03 15:00:00'公共类型
/** 年份入参:支持数字或纯数字字符串(如 2024 / '2024') */
type YearInput = number | string
/** 日期入参:支持 'YYYY-MM'、'YYYY-MM-DD' 及斜杠变体(允许带时间部分)或 Date 对象 */
type DateInput = string | Date
/** diff 的差值单位 */
type DiffUnit = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'ms'错误处理约定
本库为纯函数风格,公开 API 不抛异常。两类函数约定不同:
- 值类函数(
format/formatDate/getDays/diff等):非法入参回退默认值 (当前时间 / 本月 / 今年),保证总有返回值; - 判定类函数(
isValid/isToday/isSameDay/isBefore/isAfter):非法入参一律返回false,不做回退; - 解析函数(
parseDate)与fromNow:非法入参返回null/''。
唯一会抛错的是对 datefmt 冻结命名空间的改写(TypeError)。
模块产物
| 产物 | 路径 | 说明 |
|---|---|---|
| ESM | dist/index.js | import 引入 |
| CJS | dist/index.cjs | require 引入 |
| 类型 | dist/index.d.ts | TypeScript |
sideEffects: false,支持 tree-shaking;无 UMD 产物。