@planarcat/js-toolkit 1.5.6 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -5
- package/dist/date/compileDateFormatter.d.ts +16 -0
- package/dist/date/compileDateFormatter.d.ts.map +1 -0
- package/dist/date/compileDateFormatter.js +316 -0
- package/dist/date/compileDateFormatter.js.map +1 -0
- package/dist/date/formatDate.d.ts +81 -16
- package/dist/date/formatDate.d.ts.map +1 -1
- package/dist/date/formatDate.js +114 -130
- package/dist/date/formatDate.js.map +1 -1
- package/dist/date/formatDateCompiled.d.ts +30 -0
- package/dist/date/formatDateCompiled.d.ts.map +1 -0
- package/dist/date/formatDateCompiled.js +126 -0
- package/dist/date/formatDateCompiled.js.map +1 -0
- package/dist/date/formatDatePlain.d.ts +34 -0
- package/dist/date/formatDatePlain.d.ts.map +1 -0
- package/dist/date/formatDatePlain.js +128 -0
- package/dist/date/formatDatePlain.js.map +1 -0
- package/dist/date/regularDateFormatter.d.ts +33 -0
- package/dist/date/regularDateFormatter.d.ts.map +1 -0
- package/dist/date/regularDateFormatter.js +302 -0
- package/dist/date/regularDateFormatter.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/object/toFormattedNumber.d.ts +2 -2
- package/dist/object/toFormattedNumber.d.ts.map +1 -1
- package/dist/object/toFormattedNumber.js +8 -8
- package/dist/object/toFormattedNumber.js.map +1 -1
- package/dist/object/toFormattedNumberString.d.ts +2 -2
- package/dist/object/toFormattedNumberString.d.ts.map +1 -1
- package/dist/object/toFormattedNumberString.js +13 -9
- package/dist/object/toFormattedNumberString.js.map +1 -1
- package/dist/types/date.d.ts +19 -2
- package/dist/types/date.d.ts.map +1 -1
- package/dist/types/object.d.ts.map +1 -1
- package/dist/utils/cache.d.ts +38 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +69 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +5 -13
- package/dist/utils/constants.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ const debouncedFn = debounce(
|
|
|
57
57
|
() => {
|
|
58
58
|
console.log('函数执行了!');
|
|
59
59
|
},
|
|
60
|
-
{ delay: 500 }
|
|
60
|
+
{ delay: 500 },
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
// 多次调用,只会执行最后一次
|
|
@@ -93,7 +93,7 @@ console.log(
|
|
|
93
93
|
toFormattedNumber([
|
|
94
94
|
[1, '1.23'],
|
|
95
95
|
['45.67', [89.01, 'abc']],
|
|
96
|
-
])
|
|
96
|
+
]),
|
|
97
97
|
);
|
|
98
98
|
// 输出: [[1, 1.23], [45.67, [89.01, NaN]]]
|
|
99
99
|
|
|
@@ -124,7 +124,7 @@ console.log(
|
|
|
124
124
|
toFormattedNumberString(0.1234, {
|
|
125
125
|
preProcessor: (original, num) => num * 100,
|
|
126
126
|
suffix: '%',
|
|
127
|
-
})
|
|
127
|
+
}),
|
|
128
128
|
);
|
|
129
129
|
// 输出: "12.34%"
|
|
130
130
|
|
|
@@ -132,7 +132,7 @@ console.log(
|
|
|
132
132
|
console.log(
|
|
133
133
|
toFormattedNumberString(123.456, {
|
|
134
134
|
prefix: (original, num, formatted) => `$${Math.floor(num)}`,
|
|
135
|
-
})
|
|
135
|
+
}),
|
|
136
136
|
);
|
|
137
137
|
// 输出: "$123123.456"
|
|
138
138
|
|
|
@@ -140,7 +140,7 @@ console.log(
|
|
|
140
140
|
console.log(
|
|
141
141
|
toFormattedNumberString(123.456, {
|
|
142
142
|
suffix: (original, num, formatted) => `/${num.toFixed(0)}`,
|
|
143
|
-
})
|
|
143
|
+
}),
|
|
144
144
|
);
|
|
145
145
|
// 输出: "123.456/123"
|
|
146
146
|
|
|
@@ -248,6 +248,28 @@ npm run test:coverage
|
|
|
248
248
|
|
|
249
249
|
## 更新日志
|
|
250
250
|
|
|
251
|
+
### v1.7.0
|
|
252
|
+
|
|
253
|
+
- ✨ 优化日期格式化功能,移除了 `dddd` 和 `ddd` 标记
|
|
254
|
+
- ✨ 使用 `dd` 标记显示完整星期名称(周一、Monday)
|
|
255
|
+
- ✨ 新增自定义周名称映射功能,支持:
|
|
256
|
+
- 数组格式:`['星期日', '星期一', ...]`
|
|
257
|
+
- 完整映射:`{ zh: ['周日', ...], en: ['Sun', ...] }`
|
|
258
|
+
- ✨ 支持自动模式检测,根据调用频率自动切换普通/编译模式
|
|
259
|
+
- ✨ 优化编译模式性能,使用 LRU 缓存存储编译后的格式化函数
|
|
260
|
+
- ✨ 修复了模板字符串嵌套错误和类型安全问题
|
|
261
|
+
|
|
262
|
+
### v1.6.0
|
|
263
|
+
|
|
264
|
+
- ✨ 增强了日期格式化功能,支持更多格式化标记
|
|
265
|
+
- ✨ 新增月份相关标记:`MMMM`(完整月份名称)、`MMM`(月份缩写)
|
|
266
|
+
- ✨ 新增日期相关标记:`DDD`(一年中的第几天)、`Do`(带序数词的日期)
|
|
267
|
+
- ✨ 新增时间相关标记:`S`(单个毫秒)
|
|
268
|
+
- ✨ 新增星期相关标记:`dddd`(完整星期名称)、`ddd`(星期缩写)
|
|
269
|
+
- ✨ 新增时间戳相关标记:`X`(Unix时间戳秒)、`x`(Unix时间戳毫秒)
|
|
270
|
+
- ✨ 优化了文档结构,添加了完整的格式化标记参考
|
|
271
|
+
- ✨ 完善了测试用例,覆盖所有新功能
|
|
272
|
+
|
|
251
273
|
### v1.5.6
|
|
252
274
|
|
|
253
275
|
- ✨ 优化了 `toFormattedNumberString` 函数的内部实现,将内部函数提取到外部
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 日期格式化编译函数
|
|
3
|
+
* 将格式化字符串编译为高效的处理函数
|
|
4
|
+
*/
|
|
5
|
+
import { DateFormatOptions } from '../types/date';
|
|
6
|
+
/**
|
|
7
|
+
* 编译后的日期格式化函数类型
|
|
8
|
+
*/
|
|
9
|
+
export type CompiledFormatter = (date: Date, options?: Partial<DateFormatOptions>) => string;
|
|
10
|
+
/**
|
|
11
|
+
* 将格式化字符串编译为可直接执行的函数
|
|
12
|
+
* @param formatStr 格式化字符串
|
|
13
|
+
* @returns 编译后的格式化函数
|
|
14
|
+
*/
|
|
15
|
+
export declare function compileDateFormatter(formatStr: string): CompiledFormatter;
|
|
16
|
+
//# sourceMappingURL=compileDateFormatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compileDateFormatter.d.ts","sourceRoot":"","sources":["../../src/date/compileDateFormatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,KAAK,MAAM,CAAC;AAQ7F;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CA0SzE"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 日期格式化编译函数
|
|
4
|
+
* 将格式化字符串编译为高效的处理函数
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.compileDateFormatter = void 0;
|
|
8
|
+
const cache_1 = require("../utils/cache");
|
|
9
|
+
/**
|
|
10
|
+
* 编译后的日期格式化函数缓存
|
|
11
|
+
* 用于存储编译后的格式化函数,避免重复编译
|
|
12
|
+
*/
|
|
13
|
+
const compiledFormatCache = new cache_1.LRUCache(100);
|
|
14
|
+
/**
|
|
15
|
+
* 将格式化字符串编译为可直接执行的函数
|
|
16
|
+
* @param formatStr 格式化字符串
|
|
17
|
+
* @returns 编译后的格式化函数
|
|
18
|
+
*/
|
|
19
|
+
function compileDateFormatter(formatStr) {
|
|
20
|
+
// 检查缓存中是否已有编译后的函数
|
|
21
|
+
const cachedFormatter = compiledFormatCache.get(formatStr);
|
|
22
|
+
if (cachedFormatter) {
|
|
23
|
+
return cachedFormatter;
|
|
24
|
+
}
|
|
25
|
+
// 生成函数代码
|
|
26
|
+
const code = `
|
|
27
|
+
// 默认格式化选项
|
|
28
|
+
const DEFAULT_DATE_FORMAT_OPTIONS = { timeZone: "local", locale: "zh-CN" };
|
|
29
|
+
// 周几中英文映射
|
|
30
|
+
const WEEKDAY_MAP = { zh: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"], en: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] };
|
|
31
|
+
|
|
32
|
+
// 获取合并后的选项
|
|
33
|
+
const mergedOptions = { ...DEFAULT_DATE_FORMAT_OPTIONS, ...options };
|
|
34
|
+
|
|
35
|
+
// 获取日期各部分
|
|
36
|
+
const year = date.getFullYear();
|
|
37
|
+
const month = date.getMonth() + 1;
|
|
38
|
+
const day = date.getDate();
|
|
39
|
+
const hours = date.getHours();
|
|
40
|
+
const minutes = date.getMinutes();
|
|
41
|
+
const seconds = date.getSeconds();
|
|
42
|
+
const milliseconds = date.getMilliseconds();
|
|
43
|
+
const weekday = date.getDay();
|
|
44
|
+
const quarter = Math.floor((date.getMonth() + 3) / 3);
|
|
45
|
+
|
|
46
|
+
// 一年中的第几天
|
|
47
|
+
const firstDayOfYear = new Date(year, 0, 1);
|
|
48
|
+
const dayOfYear = Math.ceil((date.getTime() - firstDayOfYear.getTime()) / (1000 * 60 * 60 * 24));
|
|
49
|
+
|
|
50
|
+
// Unix 时间戳
|
|
51
|
+
const timestampSeconds = Math.floor(date.getTime() / 1000);
|
|
52
|
+
const timestampMilliseconds = date.getTime();
|
|
53
|
+
|
|
54
|
+
// 12小时制
|
|
55
|
+
const hours12 = hours % 12 || 12;
|
|
56
|
+
const ampm = hours < 12 ? "AM" : "PM";
|
|
57
|
+
const ampmLower = ampm.toLowerCase();
|
|
58
|
+
|
|
59
|
+
// 获取本地化的星期几
|
|
60
|
+
const getLocalizedWeekday = function(weekday, options) {
|
|
61
|
+
const lang = options.locale?.split("-")[0] || "zh";
|
|
62
|
+
|
|
63
|
+
// 处理自定义周名称映射
|
|
64
|
+
if (options.weekdayNames) {
|
|
65
|
+
if (Array.isArray(options.weekdayNames)) {
|
|
66
|
+
// 如果是数组,只替换当前语言的周名称
|
|
67
|
+
return options.weekdayNames[weekday] || WEEKDAY_MAP[lang]?.[weekday] || WEEKDAY_MAP.zh[weekday] || "日";
|
|
68
|
+
} else {
|
|
69
|
+
// 如果是Record,检查是否有当前语言的映射,否则使用默认
|
|
70
|
+
if (options.weekdayNames[lang]) {
|
|
71
|
+
return options.weekdayNames[lang][weekday] || WEEKDAY_MAP[lang]?.[weekday] || WEEKDAY_MAP.zh[weekday] || "日";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 使用默认周名称映射
|
|
77
|
+
return WEEKDAY_MAP[lang]?.[weekday] || WEEKDAY_MAP.zh[weekday] || "日";
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// 月份名称和缩写
|
|
81
|
+
const getMonthName = function(date, locale, full) {
|
|
82
|
+
if (full === undefined) full = false;
|
|
83
|
+
return date.toLocaleString(locale, { month: full ? "long" : "short" });
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// 周数计算
|
|
87
|
+
const getWeekNumber = function(date) {
|
|
88
|
+
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
|
89
|
+
const dayNum = d.getUTCDay() || 7;
|
|
90
|
+
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
|
|
91
|
+
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
|
|
92
|
+
return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const weekNumber = getWeekNumber(date);
|
|
96
|
+
|
|
97
|
+
// 处理自定义格式化器
|
|
98
|
+
let finalFormat = "${formatStr}";
|
|
99
|
+
if (mergedOptions.customFormatters) {
|
|
100
|
+
// 直接替换原始格式字符串中的自定义标记
|
|
101
|
+
// 不使用复杂的正则表达式,避免模板字符串语法冲突
|
|
102
|
+
Object.entries(mergedOptions.customFormatters).forEach(function([token, formatter]) {
|
|
103
|
+
// 简单的字符串替换,确保只替换完整标记
|
|
104
|
+
let index = finalFormat.indexOf(token);
|
|
105
|
+
while (index !== -1) {
|
|
106
|
+
// 检查前后是否为字母数字字符
|
|
107
|
+
const prevChar = index > 0 ? finalFormat[index - 1] : '';
|
|
108
|
+
const nextChar = index + token.length < finalFormat.length ? finalFormat[index + token.length] : '';
|
|
109
|
+
const isPrevAlphaNum = /[a-zA-Z0-9]/.test(prevChar);
|
|
110
|
+
const isNextAlphaNum = /[a-zA-Z0-9]/.test(nextChar);
|
|
111
|
+
|
|
112
|
+
if (!isPrevAlphaNum && !isNextAlphaNum) {
|
|
113
|
+
// 替换完整标记
|
|
114
|
+
const before = finalFormat.slice(0, index);
|
|
115
|
+
const after = finalFormat.slice(index + token.length);
|
|
116
|
+
finalFormat = before + formatter(date) + after;
|
|
117
|
+
index = before.length + formatter(date).length;
|
|
118
|
+
} else {
|
|
119
|
+
// 跳过部分匹配
|
|
120
|
+
index = finalFormat.indexOf(token, index + 1);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 初始化结果
|
|
127
|
+
let result = "";
|
|
128
|
+
let i = 0;
|
|
129
|
+
const length = finalFormat.length;
|
|
130
|
+
|
|
131
|
+
// 解析格式化字符串
|
|
132
|
+
while (i < length) {
|
|
133
|
+
let found = false;
|
|
134
|
+
|
|
135
|
+
// 1. 4字符标记
|
|
136
|
+
if (i + 4 <= length) {
|
|
137
|
+
const token4 = finalFormat.slice(i, i + 4);
|
|
138
|
+
switch (token4) {
|
|
139
|
+
case 'YYYY':
|
|
140
|
+
result += year.toString().padStart(4, "0");
|
|
141
|
+
i += 4;
|
|
142
|
+
found = true;
|
|
143
|
+
break;
|
|
144
|
+
case 'MMMM':
|
|
145
|
+
result += getMonthName(date, mergedOptions.locale || DEFAULT_DATE_FORMAT_OPTIONS.locale, true);
|
|
146
|
+
i += 4;
|
|
147
|
+
found = true;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// 3. 3字符标记
|
|
152
|
+
if (!found && i + 3 <= length) {
|
|
153
|
+
const token3 = finalFormat.slice(i, i + 3);
|
|
154
|
+
switch (token3) {
|
|
155
|
+
case 'YYY':
|
|
156
|
+
result += year.toString();
|
|
157
|
+
i += 3;
|
|
158
|
+
found = true;
|
|
159
|
+
break;
|
|
160
|
+
case 'MMM':
|
|
161
|
+
result += getMonthName(date, mergedOptions.locale || DEFAULT_DATE_FORMAT_OPTIONS.locale, false);
|
|
162
|
+
i += 3;
|
|
163
|
+
found = true;
|
|
164
|
+
break;
|
|
165
|
+
case 'DDD':
|
|
166
|
+
result += dayOfYear.toString().padStart(3, "0");
|
|
167
|
+
i += 3;
|
|
168
|
+
found = true;
|
|
169
|
+
break;
|
|
170
|
+
case 'HHH':
|
|
171
|
+
result += hours.toString().padStart(3, "0");
|
|
172
|
+
i += 3;
|
|
173
|
+
found = true;
|
|
174
|
+
break;
|
|
175
|
+
case 'hhh':
|
|
176
|
+
result += hours12.toString().padStart(3, "0");
|
|
177
|
+
i += 3;
|
|
178
|
+
found = true;
|
|
179
|
+
break;
|
|
180
|
+
case 'mmm':
|
|
181
|
+
result += minutes.toString().padStart(3, "0");
|
|
182
|
+
i += 3;
|
|
183
|
+
found = true;
|
|
184
|
+
break;
|
|
185
|
+
case 'sss':
|
|
186
|
+
result += seconds.toString().padStart(3, "0");
|
|
187
|
+
i += 3;
|
|
188
|
+
found = true;
|
|
189
|
+
break;
|
|
190
|
+
case 'SSS':
|
|
191
|
+
result += milliseconds.toString().padStart(3, "0");
|
|
192
|
+
i += 3;
|
|
193
|
+
found = true;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// 4. 2字符标记
|
|
198
|
+
if (!found && i + 2 <= length) {
|
|
199
|
+
const token2 = finalFormat.slice(i, i + 2);
|
|
200
|
+
switch (token2) {
|
|
201
|
+
case 'YY':
|
|
202
|
+
result += year.toString().slice(-2);
|
|
203
|
+
i += 2;
|
|
204
|
+
found = true;
|
|
205
|
+
break;
|
|
206
|
+
case 'MM':
|
|
207
|
+
result += month.toString().padStart(2, "0");
|
|
208
|
+
i += 2;
|
|
209
|
+
found = true;
|
|
210
|
+
break;
|
|
211
|
+
case 'DD':
|
|
212
|
+
result += day.toString().padStart(2, "0");
|
|
213
|
+
i += 2;
|
|
214
|
+
found = true;
|
|
215
|
+
break;
|
|
216
|
+
case 'HH':
|
|
217
|
+
result += hours.toString().padStart(2, "0");
|
|
218
|
+
i += 2;
|
|
219
|
+
found = true;
|
|
220
|
+
break;
|
|
221
|
+
case 'hh':
|
|
222
|
+
result += hours12.toString().padStart(2, "0");
|
|
223
|
+
i += 2;
|
|
224
|
+
found = true;
|
|
225
|
+
break;
|
|
226
|
+
case 'mm':
|
|
227
|
+
result += minutes.toString().padStart(2, "0");
|
|
228
|
+
i += 2;
|
|
229
|
+
found = true;
|
|
230
|
+
break;
|
|
231
|
+
case 'ss':
|
|
232
|
+
result += seconds.toString().padStart(2, "0");
|
|
233
|
+
i += 2;
|
|
234
|
+
found = true;
|
|
235
|
+
break;
|
|
236
|
+
case 'WW':
|
|
237
|
+
result += weekNumber.toString().padStart(2, "0");
|
|
238
|
+
i += 2;
|
|
239
|
+
found = true;
|
|
240
|
+
break;
|
|
241
|
+
case 'dd':
|
|
242
|
+
result += getLocalizedWeekday(weekday, mergedOptions);
|
|
243
|
+
i += 2;
|
|
244
|
+
found = true;
|
|
245
|
+
break;
|
|
246
|
+
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// 5. 单字符标记
|
|
250
|
+
if (!found) {
|
|
251
|
+
const token = finalFormat[i];
|
|
252
|
+
switch (token) {
|
|
253
|
+
case 'Y':
|
|
254
|
+
result += year.toString();
|
|
255
|
+
break;
|
|
256
|
+
case 'M':
|
|
257
|
+
result += month.toString();
|
|
258
|
+
break;
|
|
259
|
+
case 'D':
|
|
260
|
+
result += day.toString();
|
|
261
|
+
break;
|
|
262
|
+
case 'H':
|
|
263
|
+
result += hours.toString();
|
|
264
|
+
break;
|
|
265
|
+
case 'h':
|
|
266
|
+
result += hours12.toString();
|
|
267
|
+
break;
|
|
268
|
+
case 'm':
|
|
269
|
+
result += minutes.toString();
|
|
270
|
+
break;
|
|
271
|
+
case 's':
|
|
272
|
+
result += seconds.toString();
|
|
273
|
+
break;
|
|
274
|
+
case 'S':
|
|
275
|
+
result += milliseconds.toString();
|
|
276
|
+
break;
|
|
277
|
+
case 'W':
|
|
278
|
+
result += weekNumber.toString();
|
|
279
|
+
break;
|
|
280
|
+
case 'd':
|
|
281
|
+
result += weekday.toString();
|
|
282
|
+
break;
|
|
283
|
+
case 'Q':
|
|
284
|
+
result += quarter.toString();
|
|
285
|
+
break;
|
|
286
|
+
case 'A':
|
|
287
|
+
result += ampm;
|
|
288
|
+
break;
|
|
289
|
+
case 'a':
|
|
290
|
+
result += ampmLower;
|
|
291
|
+
break;
|
|
292
|
+
|
|
293
|
+
case 'X':
|
|
294
|
+
result += timestampSeconds;
|
|
295
|
+
break;
|
|
296
|
+
case 'x':
|
|
297
|
+
result += timestampMilliseconds;
|
|
298
|
+
break;
|
|
299
|
+
default:
|
|
300
|
+
result += token;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
i++;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return result;
|
|
308
|
+
`;
|
|
309
|
+
// 使用 new Function() 生成函数
|
|
310
|
+
const formatter = new Function('date', 'options', code);
|
|
311
|
+
// 缓存编译后的函数
|
|
312
|
+
compiledFormatCache.set(formatStr, formatter);
|
|
313
|
+
return formatter;
|
|
314
|
+
}
|
|
315
|
+
exports.compileDateFormatter = compileDateFormatter;
|
|
316
|
+
//# sourceMappingURL=compileDateFormatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compileDateFormatter.js","sourceRoot":"","sources":["../../src/date/compileDateFormatter.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,0CAA0C;AAO1C;;;GAGG;AACH,MAAM,mBAAmB,GAAG,IAAI,gBAAQ,CAA4B,GAAG,CAAC,CAAC;AAEzE;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,SAAiB;IAClD,kBAAkB;IAClB,MAAM,eAAe,GAAG,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3D,IAAI,eAAe,EAAE,CAAC;QAClB,OAAO,eAAe,CAAC;IAC3B,CAAC;IACD,SAAS;IACT,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAwEQ,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkN/B,CAAC;IAEA,yBAAyB;IACzB,MAAM,SAAS,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAsB,CAAC;IAE7E,WAAW;IACX,mBAAmB,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAE9C,OAAO,SAAS,CAAC;AACrB,CAAC;AA1SD,oDA0SC"}
|
|
@@ -11,7 +11,7 @@ import { DateFormatOptions, DateInput } from '../types/date';
|
|
|
11
11
|
* ```typescript
|
|
12
12
|
* import { formatDate } from '@planarcat/js-toolkit';
|
|
13
13
|
*
|
|
14
|
-
* // 基本使用(默认格式 'YYYY-MM-DD HH:mm:ss'
|
|
14
|
+
* // 基本使用(默认格式 'YYYY-MM-DD HH:mm:ss',默认自动模式)
|
|
15
15
|
* formatDate(new Date());
|
|
16
16
|
* // 返回: "2023-12-25 14:30:45"
|
|
17
17
|
*
|
|
@@ -19,22 +19,87 @@ import { DateFormatOptions, DateInput } from '../types/date';
|
|
|
19
19
|
* formatDate('2023-12-25', 'YYYY年MM月DD日');
|
|
20
20
|
* // 返回: "2023年12月25日"
|
|
21
21
|
*
|
|
22
|
-
* //
|
|
23
|
-
* formatDate(new Date(), '
|
|
24
|
-
* // 返回: "
|
|
25
|
-
*
|
|
26
|
-
* //
|
|
27
|
-
* formatDate(new Date(), '
|
|
28
|
-
* // 返回: "
|
|
29
|
-
*
|
|
30
|
-
* //
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* });
|
|
36
|
-
* // 返回: "第4季度"
|
|
22
|
+
* // 指定编译模式
|
|
23
|
+
* formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss', { mode: 'compile' });
|
|
24
|
+
* // 返回: "2023-12-25 14:30:45"
|
|
25
|
+
*
|
|
26
|
+
* // 指定普通模式
|
|
27
|
+
* formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss', { mode: 'regular' });
|
|
28
|
+
* // 返回: "2023-12-25 14:30:45"
|
|
29
|
+
*
|
|
30
|
+
* // 自动模式性能测试
|
|
31
|
+
* // 首次调用使用普通模式,第二次及以后自动切换到编译模式
|
|
32
|
+
* for (let i = 0; i < 1000; i++) {
|
|
33
|
+
* formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss');
|
|
34
|
+
* }
|
|
37
35
|
* ```
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* ## 支持的格式化标记
|
|
39
|
+
*
|
|
40
|
+
* ### 年份
|
|
41
|
+
* - `YYYY`: 4位年份 (2024)
|
|
42
|
+
* - `YY`: 2位年份 (24)
|
|
43
|
+
*
|
|
44
|
+
* ### 月份
|
|
45
|
+
* - `MMMM`: 完整月份名称 (January / 一月)
|
|
46
|
+
* - `MMM`: 月份缩写 (Jan / 1月)
|
|
47
|
+
* - `MM`: 2位月份 (01-12)
|
|
48
|
+
* - `M`: 1-2位月份 (1-12)
|
|
49
|
+
*
|
|
50
|
+
* ### 日期
|
|
51
|
+
* - `DDD`: 一年中的第几天 (001-366)
|
|
52
|
+
* - `DD`: 2位日期 (01-31)
|
|
53
|
+
* - `D`: 1-2位日期 (1-31)
|
|
54
|
+
*
|
|
55
|
+
* ### 星期
|
|
56
|
+
* - `dd`: 星期名称 (Monday / 周一)
|
|
57
|
+
* - `d`: 星期数字 (0-6, 0=周日)
|
|
58
|
+
*
|
|
59
|
+
* ### 时间
|
|
60
|
+
* - `HH`: 24小时制,2位 (00-23)
|
|
61
|
+
* - `H`: 24小时制,1-2位 (0-23)
|
|
62
|
+
* - `hh`: 12小时制,2位 (01-12)
|
|
63
|
+
* - `h`: 12小时制,1-2位 (1-12)
|
|
64
|
+
* - `mm`: 2位分钟 (00-59)
|
|
65
|
+
* - `m`: 1-2位分钟 (0-59)
|
|
66
|
+
* - `ss`: 2位秒 (00-59)
|
|
67
|
+
* - `s`: 1-2位秒 (0-59)
|
|
68
|
+
* - `SSS`: 3位毫秒 (000-999)
|
|
69
|
+
* - `S`: 毫秒 (000-999)
|
|
70
|
+
*
|
|
71
|
+
* ### 其他
|
|
72
|
+
* - `A`: 大写AM/PM
|
|
73
|
+
* - `a`: 小写am/pm
|
|
74
|
+
* - `Q`: 季度 (1-4)
|
|
75
|
+
* - `WW`: 2位周数 (01-53)
|
|
76
|
+
* - `W`: 1-2位周数 (1-53)
|
|
77
|
+
* - `X`: Unix时间戳 (秒)
|
|
78
|
+
* - `x`: Unix时间戳 (毫秒)
|
|
79
|
+
*
|
|
80
|
+
* ## 格式化模式
|
|
81
|
+
*
|
|
82
|
+
* - **自动模式 (auto)**:默认模式,根据调用次数自动切换
|
|
83
|
+
* - 首次调用:使用普通模式,避免编译开销
|
|
84
|
+
* - 重复调用:达到阈值后自动切换到编译模式
|
|
85
|
+
* - 智能优化:平衡首次调用性能和重复调用性能
|
|
86
|
+
*
|
|
87
|
+
* - **普通模式 (regular)**:直接解析格式化字符串,不使用缓存
|
|
88
|
+
* - 适合单次或少量调用
|
|
89
|
+
* - 无需编译和缓存开销
|
|
90
|
+
* - 内存占用较小
|
|
91
|
+
*
|
|
92
|
+
* - **编译模式 (compile)**:通过缓存编译后的格式化函数,显著提升频繁调用时的性能
|
|
93
|
+
* - 首次调用:编译格式化字符串,生成高效的处理函数
|
|
94
|
+
* - 后续调用:直接使用缓存的处理函数,跳过解析步骤
|
|
95
|
+
* - 缓存策略:使用LRU缓存,最大容量100
|
|
96
|
+
* - 性能提升:简单格式提升3-5倍,复杂格式提升10倍以上
|
|
97
|
+
*
|
|
98
|
+
* ## 模式选择建议
|
|
99
|
+
*
|
|
100
|
+
* - **自动模式**:推荐使用,适合大多数场景,智能平衡性能和开销
|
|
101
|
+
* - **普通模式**:适用于单次或少量调用不同格式字符串的场景
|
|
102
|
+
* - **编译模式**:适用于频繁调用相同格式字符串的场景,如循环格式化大量日期
|
|
38
103
|
*/
|
|
39
104
|
declare function formatDate(input: DateInput, formatStr?: string, options?: Partial<DateFormatOptions>): string;
|
|
40
105
|
export default formatDate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatDate.d.ts","sourceRoot":"","sources":["../../src/date/formatDate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"formatDate.d.ts","sourceRoot":"","sources":["../../src/date/formatDate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAU7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqGG;AACH,iBAAS,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,GAAE,MAA8B,EAAE,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAM,GAAG,MAAM,CA6BjI;AAED,eAAe,UAAU,CAAC"}
|