react-util-tools 1.0.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.
@@ -0,0 +1,374 @@
1
+ import {
2
+ parseISO,
3
+ isValid,
4
+ addDays,
5
+ addMonths,
6
+ subDays,
7
+ subMonths,
8
+ startOfDay,
9
+ endOfDay,
10
+ startOfMonth,
11
+ endOfMonth,
12
+ startOfWeek,
13
+ endOfWeek,
14
+ differenceInDays,
15
+ differenceInHours,
16
+ differenceInMinutes,
17
+ getISOWeek,
18
+ getISOWeeksInYear,
19
+ setISOWeek
20
+ } from 'date-fns'
21
+ import { formatInTimeZone, toZonedTime, fromZonedTime } from 'date-fns-tz'
22
+
23
+ const UTC_TIMEZONE = 'UTC'
24
+
25
+ /**
26
+ * 将本地时间转换为 UTC 时间
27
+ * @param date 本地日期对象、时间戳或日期字符串
28
+ * @returns UTC Date 对象
29
+ */
30
+ export function toUTC(date: Date | number | string): Date {
31
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
32
+ return fromZonedTime(dateObj, Intl.DateTimeFormat().resolvedOptions().timeZone)
33
+ }
34
+
35
+ /**
36
+ * 将 UTC 时间转换为本地时间
37
+ * @param utcDate UTC 日期对象、时间戳或日期字符串
38
+ * @returns 本地 Date 对象
39
+ */
40
+ export function fromUTC(utcDate: Date | number | string): Date {
41
+ const dateObj = typeof utcDate === 'string' ? parseISO(utcDate) : new Date(utcDate)
42
+ return toZonedTime(dateObj, Intl.DateTimeFormat().resolvedOptions().timeZone)
43
+ }
44
+
45
+ /**
46
+ * 格式化为 UTC 时间字符串
47
+ * @param date 日期对象、时间戳或日期字符串
48
+ * @param formatStr 格式化字符串,默认 'yyyy-MM-dd HH:mm:ss'
49
+ * @returns UTC 时间字符串
50
+ */
51
+ export function formatUTC(
52
+ date: Date | number | string,
53
+ formatStr = 'yyyy-MM-dd HH:mm:ss'
54
+ ): string {
55
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
56
+ if (!isValid(dateObj)) return ''
57
+
58
+ return formatInTimeZone(dateObj, UTC_TIMEZONE, formatStr)
59
+ }
60
+
61
+ /**
62
+ * 格式化为 UTC 日期(不含时间)
63
+ * @param date 日期对象、时间戳或日期字符串
64
+ * @returns UTC 日期字符串 'yyyy-MM-dd'
65
+ */
66
+ export function formatUTCDateOnly(date: Date | number | string): string {
67
+ return formatUTC(date, 'yyyy-MM-dd')
68
+ }
69
+
70
+ /**
71
+ * 格式化为 UTC 时间(不含日期)
72
+ * @param date 日期对象、时间戳或日期字符串
73
+ * @returns UTC 时间字符串 'HH:mm:ss'
74
+ */
75
+ export function formatUTCTimeOnly(date: Date | number | string): string {
76
+ return formatUTC(date, 'HH:mm:ss')
77
+ }
78
+
79
+ /**
80
+ * 格式化为 ISO 8601 UTC 字符串
81
+ * @param date 日期对象、时间戳或日期字符串
82
+ * @returns ISO 8601 格式的 UTC 字符串
83
+ */
84
+ export function toISOString(date: Date | number | string): string {
85
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
86
+ return dateObj.toISOString()
87
+ }
88
+
89
+ /**
90
+ * 获取 UTC 当前时间
91
+ * @returns UTC Date 对象
92
+ */
93
+ export function getUTCNow(): Date {
94
+ return new Date()
95
+ }
96
+
97
+ /**
98
+ * 获取 UTC 当前时间戳(毫秒)
99
+ * @returns UTC 时间戳
100
+ */
101
+ export function getUTCTimestamp(): number {
102
+ return Date.now()
103
+ }
104
+
105
+ /**
106
+ * 获取 UTC 当前时间戳(秒)
107
+ * @returns UTC 时间戳
108
+ */
109
+ export function getUTCTimestampInSeconds(): number {
110
+ return Math.floor(Date.now() / 1000)
111
+ }
112
+
113
+ /**
114
+ * 获取 UTC 一天的开始时间(00:00:00)
115
+ * @param date 日期对象、时间戳或日期字符串
116
+ * @returns UTC Date 对象
117
+ */
118
+ export function getUTCStartOfDay(date: Date | number | string): Date {
119
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
120
+ const utcDate = toZonedTime(dateObj, UTC_TIMEZONE)
121
+ return startOfDay(utcDate)
122
+ }
123
+
124
+ /**
125
+ * 获取 UTC 一天的结束时间(23:59:59)
126
+ * @param date 日期对象、时间戳或日期字符串
127
+ * @returns UTC Date 对象
128
+ */
129
+ export function getUTCEndOfDay(date: Date | number | string): Date {
130
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
131
+ const utcDate = toZonedTime(dateObj, UTC_TIMEZONE)
132
+ return endOfDay(utcDate)
133
+ }
134
+
135
+ /**
136
+ * 获取 UTC 一个月的开始时间
137
+ * @param date 日期对象、时间戳或日期字符串
138
+ * @returns UTC Date 对象
139
+ */
140
+ export function getUTCStartOfMonth(date: Date | number | string): Date {
141
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
142
+ const utcDate = toZonedTime(dateObj, UTC_TIMEZONE)
143
+ return startOfMonth(utcDate)
144
+ }
145
+
146
+ /**
147
+ * 获取 UTC 一个月的结束时间
148
+ * @param date 日期对象、时间戳或日期字符串
149
+ * @returns UTC Date 对象
150
+ */
151
+ export function getUTCEndOfMonth(date: Date | number | string): Date {
152
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
153
+ const utcDate = toZonedTime(dateObj, UTC_TIMEZONE)
154
+ return endOfMonth(utcDate)
155
+ }
156
+
157
+ /**
158
+ * UTC 时间增加天数
159
+ * @param date 日期对象、时间戳或日期字符串
160
+ * @param amount 天数
161
+ * @returns UTC Date 对象
162
+ */
163
+ export function addDaysUTC(date: Date | number | string, amount: number): Date {
164
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
165
+ return addDays(dateObj, amount)
166
+ }
167
+
168
+ /**
169
+ * UTC 时间减少天数
170
+ * @param date 日期对象、时间戳或日期字符串
171
+ * @param amount 天数
172
+ * @returns UTC Date 对象
173
+ */
174
+ export function subDaysUTC(date: Date | number | string, amount: number): Date {
175
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
176
+ return subDays(dateObj, amount)
177
+ }
178
+
179
+ /**
180
+ * UTC 时间增加月数
181
+ * @param date 日期对象、时间戳或日期字符串
182
+ * @param amount 月数
183
+ * @returns UTC Date 对象
184
+ */
185
+ export function addMonthsUTC(date: Date | number | string, amount: number): Date {
186
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
187
+ return addMonths(dateObj, amount)
188
+ }
189
+
190
+ /**
191
+ * UTC 时间减少月数
192
+ * @param date 日期对象、时间戳或日期字符串
193
+ * @param amount 月数
194
+ * @returns UTC Date 对象
195
+ */
196
+ export function subMonthsUTC(date: Date | number | string, amount: number): Date {
197
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
198
+ return subMonths(dateObj, amount)
199
+ }
200
+
201
+ /**
202
+ * 计算两个 UTC 时间之间的天数差
203
+ * @param dateLeft 较晚的日期
204
+ * @param dateRight 较早的日期
205
+ * @returns 天数差
206
+ */
207
+ export function getUTCDaysDiff(
208
+ dateLeft: Date | number | string,
209
+ dateRight: Date | number | string
210
+ ): number {
211
+ const left = typeof dateLeft === 'string' ? parseISO(dateLeft) : new Date(dateLeft)
212
+ const right = typeof dateRight === 'string' ? parseISO(dateRight) : new Date(dateRight)
213
+ return differenceInDays(left, right)
214
+ }
215
+
216
+ /**
217
+ * 计算两个 UTC 时间之间的小时差
218
+ * @param dateLeft 较晚的日期
219
+ * @param dateRight 较早的日期
220
+ * @returns 小时差
221
+ */
222
+ export function getUTCHoursDiff(
223
+ dateLeft: Date | number | string,
224
+ dateRight: Date | number | string
225
+ ): number {
226
+ const left = typeof dateLeft === 'string' ? parseISO(dateLeft) : new Date(dateLeft)
227
+ const right = typeof dateRight === 'string' ? parseISO(dateRight) : new Date(dateRight)
228
+ return differenceInHours(left, right)
229
+ }
230
+
231
+ /**
232
+ * 计算两个 UTC 时间之间的分钟差
233
+ * @param dateLeft 较晚的日期
234
+ * @param dateRight 较早的日期
235
+ * @returns 分钟差
236
+ */
237
+ export function getUTCMinutesDiff(
238
+ dateLeft: Date | number | string,
239
+ dateRight: Date | number | string
240
+ ): number {
241
+ const left = typeof dateLeft === 'string' ? parseISO(dateLeft) : new Date(dateLeft)
242
+ const right = typeof dateRight === 'string' ? parseISO(dateRight) : new Date(dateRight)
243
+ return differenceInMinutes(left, right)
244
+ }
245
+
246
+ /**
247
+ * 获取时区偏移量(分钟)
248
+ * @returns 时区偏移量,例如:中国为 -480(UTC+8)
249
+ */
250
+ export function getTimezoneOffset(): number {
251
+ return new Date().getTimezoneOffset()
252
+ }
253
+
254
+ /**
255
+ * 获取时区偏移量(小时)
256
+ * @returns 时区偏移量,例如:中国为 8(UTC+8)
257
+ */
258
+ export function getTimezoneOffsetHours(): number {
259
+ return -new Date().getTimezoneOffset() / 60
260
+ }
261
+
262
+ /**
263
+ * 获取指定年份 UTC 第一天 00:00:00 的时间戳(毫秒)
264
+ * @param year 年份,默认当前年份
265
+ * @returns 时间戳(毫秒)
266
+ */
267
+ export function getUTCYearStartTimestamp(year?: number): number {
268
+ const targetYear = year ?? new Date().getUTCFullYear()
269
+ const date = new Date(Date.UTC(targetYear, 0, 1, 0, 0, 0, 0))
270
+ return date.getTime()
271
+ }
272
+
273
+ /**
274
+ * 获取指定年份 UTC 最后一天 23:59:59 的时间戳(毫秒)
275
+ * @param year 年份,默认当前年份
276
+ * @returns 时间戳(毫秒)
277
+ */
278
+ export function getUTCYearEndTimestamp(year?: number): number {
279
+ const targetYear = year ?? new Date().getUTCFullYear()
280
+ const date = new Date(Date.UTC(targetYear, 11, 31, 23, 59, 59, 999))
281
+ return date.getTime()
282
+ }
283
+
284
+ /**
285
+ * 获取指定年份 UTC 第一天 00:00:00 的 Date 对象
286
+ * @param year 年份,默认当前年份
287
+ * @returns UTC Date 对象
288
+ */
289
+ export function getUTCYearStart(year?: number): Date {
290
+ const targetYear = year ?? new Date().getUTCFullYear()
291
+ return new Date(Date.UTC(targetYear, 0, 1, 0, 0, 0, 0))
292
+ }
293
+
294
+ /**
295
+ * 获取指定年份 UTC 最后一天 23:59:59 的 Date 对象
296
+ * @param year 年份,默认当前年份
297
+ * @returns UTC Date 对象
298
+ */
299
+ export function getUTCYearEnd(year?: number): Date {
300
+ const targetYear = year ?? new Date().getUTCFullYear()
301
+ return new Date(Date.UTC(targetYear, 11, 31, 23, 59, 59, 999))
302
+ }
303
+
304
+ /**
305
+ * 获取指定年份有多少周(ISO 周)
306
+ * @param year 年份,默认当前年份
307
+ * @returns 周数(52 或 53)
308
+ */
309
+ export function getUTCWeeksInYear(year?: number): number {
310
+ const targetYear = year ?? new Date().getUTCFullYear()
311
+ const date = new Date(Date.UTC(targetYear, 0, 1))
312
+ return getISOWeeksInYear(date)
313
+ }
314
+
315
+ /**
316
+ * 获取指定年份指定周的开始时间(周一 00:00:00 UTC)
317
+ * @param year 年份
318
+ * @param week 周数(1-53)
319
+ * @returns UTC Date 对象
320
+ */
321
+ export function getUTCWeekStart(year: number, week: number): Date {
322
+ const date = new Date(Date.UTC(year, 0, 4)) // ISO 周从第一个周四所在的周开始
323
+ const weekDate = setISOWeek(date, week)
324
+ return startOfWeek(weekDate, { weekStartsOn: 1 })
325
+ }
326
+
327
+ /**
328
+ * 获取指定年份指定周的结束时间(周日 23:59:59 UTC)
329
+ * @param year 年份
330
+ * @param week 周数(1-53)
331
+ * @returns UTC Date 对象
332
+ */
333
+ export function getUTCWeekEnd(year: number, week: number): Date {
334
+ const date = new Date(Date.UTC(year, 0, 4))
335
+ const weekDate = setISOWeek(date, week)
336
+ return endOfWeek(weekDate, { weekStartsOn: 1 })
337
+ }
338
+
339
+ /**
340
+ * 获取指定年份所有周的时间范围
341
+ * @param year 年份,默认当前年份
342
+ * @returns 包含所有周的开始和结束时间的数组
343
+ */
344
+ export function getUTCAllWeeksInYear(
345
+ year?: number
346
+ ): Array<{ week: number; start: Date; end: Date; startTimestamp: number; endTimestamp: number }> {
347
+ const targetYear = year ?? new Date().getUTCFullYear()
348
+ const weeksCount = getUTCWeeksInYear(targetYear)
349
+ const weeks: Array<{ week: number; start: Date; end: Date; startTimestamp: number; endTimestamp: number }> = []
350
+
351
+ for (let week = 1; week <= weeksCount; week++) {
352
+ const start = getUTCWeekStart(targetYear, week)
353
+ const end = getUTCWeekEnd(targetYear, week)
354
+ weeks.push({
355
+ week,
356
+ start,
357
+ end,
358
+ startTimestamp: start.getTime(),
359
+ endTimestamp: end.getTime()
360
+ })
361
+ }
362
+
363
+ return weeks
364
+ }
365
+
366
+ /**
367
+ * 获取指定日期是 UTC 时区的第几周
368
+ * @param date 日期对象、时间戳或日期字符串
369
+ * @returns 周数
370
+ */
371
+ export function getUTCWeekNumber(date: Date | number | string): number {
372
+ const dateObj = typeof date === 'string' ? parseISO(date) : new Date(date)
373
+ return getISOWeek(dateObj)
374
+ }