@cloudcome/utils-core 1.16.0 → 1.17.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/dist/core.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const type = require("./type.cjs");
3
- const TZ_OFFSET_MS = 60 * 1e3;
4
- class TzDate {
3
+ const TIMEZONE_OFFSET_MS = 60 * 1e3;
4
+ class TimezoneDate {
5
5
  /**
6
6
  * 内部时间戳
7
7
  */
@@ -17,35 +17,35 @@ class TzDate {
17
17
  /**
18
18
  * 本地时区偏移量(分钟)
19
19
  */
20
- #localTZOffset = TzDate.getOffset();
20
+ #localTimezoneOffset = TimezoneDate.getTimezoneOffset();
21
21
  /**
22
22
  * 本地时区偏移量(毫秒)
23
23
  */
24
- #localTzOffsetMS = this.#localTZOffset * TZ_OFFSET_MS;
24
+ #localTimezoneOffsetMS = this.#localTimezoneOffset * TIMEZONE_OFFSET_MS;
25
25
  /**
26
26
  * 目标时区偏移量(分钟)
27
27
  */
28
- #targetTzOffset = 0;
28
+ #targetTimezoneOffset = 0;
29
29
  /**
30
30
  * 目标时区偏移量(毫秒)
31
31
  */
32
- #targetTzOffsetMS = 0;
32
+ #targetTimezoneOffsetMS = 0;
33
33
  /**
34
34
  * 构造函数选项
35
35
  */
36
36
  #options;
37
37
  /**
38
- * 构造一个 TzDate 实例
38
+ * 构造一个 TimezoneDate 实例
39
39
  * @param options - 配置选项
40
40
  */
41
41
  constructor(options) {
42
- this.#options = (options instanceof TzDate ? {
42
+ this.#options = (options instanceof TimezoneDate ? {
43
43
  timestamp: options.getTime(),
44
- offset: options.getTimezoneOffset()
44
+ utcOffset: options.getUTCOffset()
45
45
  } : options) || {};
46
- const { offset, timestamp, value } = this.#options;
47
- this.#targetTzOffset = type.isNumber(offset) ? offset : this.#localTZOffset;
48
- this.#targetTzOffsetMS = this.#targetTzOffset * TZ_OFFSET_MS;
46
+ const { utcOffset, timestamp, value } = this.#options;
47
+ this.#targetTimezoneOffset = type.isNumber(utcOffset) ? TimezoneDate.getTimezoneOffset(utcOffset) : this.#localTimezoneOffset;
48
+ this.#targetTimezoneOffsetMS = this.#targetTimezoneOffset * TIMEZONE_OFFSET_MS;
49
49
  if (Array.isArray(value) && value.length > 0) {
50
50
  const [fullYear, month, day, hours, minutes, seconds, milliseconds] = value;
51
51
  const timestamp2 = Date.UTC(
@@ -57,33 +57,33 @@ class TzDate {
57
57
  seconds ?? 0,
58
58
  milliseconds ?? 0
59
59
  );
60
- this.#timestamp = timestamp2 + this.#targetTzOffsetMS;
60
+ this.#timestamp = timestamp2 + this.#targetTimezoneOffsetMS;
61
61
  } else {
62
62
  this.#timestamp = timestamp || Date.now();
63
63
  }
64
- this.#targetDate = new Date(this.#timestamp + this.#localTzOffsetMS - this.#targetTzOffsetMS);
65
- this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);
64
+ this.#targetDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS - this.#targetTimezoneOffsetMS);
65
+ this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);
66
66
  }
67
67
  /**
68
68
  * 更新内部时间戳
69
69
  */
70
70
  #updateTimestamp() {
71
- this.#timestamp = this.#targetDate.getTime() + this.#targetTzOffsetMS - this.#localTzOffsetMS;
72
- this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);
71
+ this.#timestamp = this.#targetDate.getTime() + this.#targetTimezoneOffsetMS - this.#localTimezoneOffsetMS;
72
+ this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);
73
73
  }
74
74
  /**
75
75
  * 获取时区偏移量(分钟)
76
76
  * @returns 时区偏移量
77
77
  */
78
78
  getTimezoneOffset() {
79
- return this.#targetTzOffset;
79
+ return this.#targetTimezoneOffset;
80
80
  }
81
81
  /**
82
- * 获取时区序号
82
+ * 获取时区偏移量(UTC)
83
83
  * @returns 时区序号
84
84
  */
85
- getTimezoneOrder() {
86
- return TzDate.getOrder(this.#targetTzOffset);
85
+ getUTCOffset() {
86
+ return TimezoneDate.getUTCOffset(this.#targetTimezoneOffset);
87
87
  }
88
88
  /**
89
89
  * 获取年份
@@ -244,40 +244,44 @@ class TzDate {
244
244
  return dateFormat(this.#utcDate, "YYYY-MM-DDTHH:mm:ss.SSSZ");
245
245
  }
246
246
  /**
247
- * 创建一个 TzDate 对象
247
+ * 转换为指定时区的 TimezoneDate 对象
248
248
  * @param td - 需要转换的日期对象
249
249
  * @param offset - 目标时区分钟偏移量,默认为当前时区
250
- * @returns 返回一个 TzDate 对象
250
+ * @returns 返回一个 TimezoneDate 对象
251
251
  * @example
252
252
  * ```js
253
- * const tzDate = TzDate.from(new TzDate());
253
+ * // 转换为 UTC 时间
254
+ * const utc0Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 0);
255
+ *
256
+ * // 转换为东八区时间
257
+ * const utc8Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 8);
254
258
  * ```
255
259
  */
256
- static from(td, offset = TzDate.getOffset()) {
257
- return new TzDate({
258
- offset,
260
+ static changeUtcOffset(td, utcOffset) {
261
+ return new TimezoneDate({
262
+ utcOffset,
259
263
  timestamp: td.getTime()
260
264
  });
261
265
  }
262
266
  /**
263
- * 获取时区序号
264
- * @param offset - 默认使用当前时区分钟偏移量
265
- * @returns 时区序号
267
+ * 获取时区分钟偏移量
268
+ * @param utcOffset - 默认使用当前时区
269
+ * @returns 时区分钟偏移量
266
270
  */
267
- static getOrder(offset = TzDate.getOffset()) {
268
- return offset / -60;
271
+ static getTimezoneOffset(utcOffset) {
272
+ return type.isNumber(utcOffset) ? utcOffset * -60 : (/* @__PURE__ */ new Date()).getTimezoneOffset();
269
273
  }
270
274
  /**
271
- * 获取时区分钟偏移量
272
- * @param gmtOrder - 默认使用当前时区序号
273
- * @returns 时区分钟偏移量
275
+ * 获取时区序号
276
+ * @param timezoneOffset - 默认使用当前时区分钟偏移量
277
+ * @returns 时区序号
274
278
  */
275
- static getOffset(gmtOrder) {
276
- return type.isNumber(gmtOrder) ? gmtOrder * -60 : (/* @__PURE__ */ new Date()).getTimezoneOffset();
279
+ static getUTCOffset(timezoneOffset = TimezoneDate.getTimezoneOffset()) {
280
+ return timezoneOffset / -60;
277
281
  }
278
282
  }
279
283
  function isValidDate(unknown) {
280
- return unknown instanceof Date && !Number.isNaN(unknown.getTime()) || unknown instanceof TzDate && !Number.isNaN(unknown.getTime());
284
+ return unknown instanceof Date && !Number.isNaN(unknown.getTime()) || unknown instanceof TimezoneDate && !Number.isNaN(unknown.getTime());
281
285
  }
282
286
  function _guessDateSeparator(value) {
283
287
  if (!type.isString(value)) return;
@@ -301,7 +305,7 @@ function _guessDateTimezone(value) {
301
305
  return d;
302
306
  }
303
307
  function dateParse(dateValue) {
304
- const d1 = type.isDate(dateValue) ? new Date(dateValue) : dateValue instanceof TzDate ? new TzDate(dateValue) : new Date(dateValue);
308
+ const d1 = type.isDate(dateValue) ? new Date(dateValue) : dateValue instanceof TimezoneDate ? new TimezoneDate(dateValue) : new Date(dateValue);
305
309
  if (isValidDate(d1)) return d1;
306
310
  const d2 = _guessDateSeparator(dateValue);
307
311
  if (isValidDate(d2)) return d2;
@@ -351,7 +355,7 @@ function dateFormat(dateValue, format = "YYYY-MM-DD HH:mm:ss") {
351
355
  }
352
356
  return result;
353
357
  }
354
- exports.TzDate = TzDate;
358
+ exports.TimezoneDate = TimezoneDate;
355
359
  exports.dateFormat = dateFormat;
356
360
  exports.dateParse = dateParse;
357
361
  exports.isValidDate = isValidDate;
package/dist/core.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.cjs","sources":["../src/date/timezone.ts","../src/date/core.ts"],"sourcesContent":["import { isNumber } from '../type';\nimport { dateFormat } from './core';\n\nexport type TzDateOptions = {\n /**\n * 时间戳\n * @default Date.now()\n */\n timestamp?: number;\n\n /**\n * 日期值\n */\n value?: readonly [\n year?: number,\n month?: number,\n day?: number,\n hours?: number,\n minutes?: number,\n seconds?: number,\n milliseconds?: number,\n ];\n\n /**\n * 时区偏移量,单位为分钟,默认为当前时区\n */\n offset?: number;\n};\n\n/**\n * 时区偏移量毫秒常量(1分钟 = 60 * 1000 毫秒)\n */\nconst TZ_OFFSET_MS = 60 * 1000;\n\n/**\n * 时区日期类,用于处理不同时区的日期时间\n */\nexport class TzDate {\n /**\n * 内部时间戳\n */\n #timestamp: number;\n\n /**\n * 目标时区的日期对象\n */\n #targetDate: Date;\n\n /**\n * UTC 日期对象\n */\n #utcDate: Date;\n\n /**\n * 本地时区偏移量(分钟)\n */\n #localTZOffset = TzDate.getOffset();\n\n /**\n * 本地时区偏移量(毫秒)\n */\n #localTzOffsetMS = this.#localTZOffset * TZ_OFFSET_MS;\n\n /**\n * 目标时区偏移量(分钟)\n */\n #targetTzOffset = 0;\n\n /**\n * 目标时区偏移量(毫秒)\n */\n #targetTzOffsetMS = 0;\n\n /**\n * 构造函数选项\n */\n #options: TzDateOptions;\n\n /**\n * 构造一个 TzDate 实例\n * @param options - 配置选项\n */\n constructor(options?: TzDateOptions | TzDate) {\n this.#options =\n (options instanceof TzDate\n ? {\n timestamp: options.getTime(),\n offset: options.getTimezoneOffset(),\n }\n : options) || {};\n const { offset, timestamp, value } = this.#options;\n this.#targetTzOffset = isNumber(offset) ? offset : this.#localTZOffset;\n this.#targetTzOffsetMS = this.#targetTzOffset * TZ_OFFSET_MS;\n\n if (Array.isArray(value) && value.length > 0) {\n const [fullYear, month, day, hours, minutes, seconds, milliseconds] = value;\n const timestamp = Date.UTC(\n fullYear ?? 0,\n month ?? 0,\n day ?? 1,\n hours ?? 0,\n minutes ?? 0,\n seconds ?? 0,\n milliseconds ?? 0,\n );\n\n this.#timestamp = timestamp + this.#targetTzOffsetMS;\n } else {\n this.#timestamp = timestamp || Date.now();\n }\n\n this.#targetDate = new Date(this.#timestamp + this.#localTzOffsetMS - this.#targetTzOffsetMS);\n this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);\n }\n\n /**\n * 更新内部时间戳\n */\n #updateTimestamp() {\n this.#timestamp = this.#targetDate.getTime() + this.#targetTzOffsetMS - this.#localTzOffsetMS;\n this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);\n }\n\n /**\n * 获取时区偏移量(分钟)\n * @returns 时区偏移量\n */\n getTimezoneOffset() {\n return this.#targetTzOffset;\n }\n\n /**\n * 获取时区序号\n * @returns 时区序号\n */\n getTimezoneOrder() {\n return TzDate.getOrder(this.#targetTzOffset);\n }\n\n /**\n * 获取年份\n * @returns 年份\n */\n getFullYear() {\n return this.#targetDate.getFullYear();\n }\n\n /**\n * 获取月份\n * @returns 月份 (0-11)\n */\n getMonth() {\n return this.#targetDate.getMonth();\n }\n\n /**\n * 获取日期\n * @returns 日期 (1-31)\n */\n getDate() {\n return this.#targetDate.getDate();\n }\n\n /**\n * 获取小时\n * @returns 小时 (0-23)\n */\n getHours() {\n return this.#targetDate.getHours();\n }\n\n /**\n * 获取分钟\n * @returns 分钟 (0-59)\n */\n getMinutes() {\n return this.#targetDate.getMinutes();\n }\n\n /**\n * 获取秒数\n * @returns 秒数 (0-59)\n */\n getSeconds() {\n return this.#targetDate.getSeconds();\n }\n\n /**\n * 获取毫秒\n * @returns 毫秒 (0-999)\n */\n getMilliseconds() {\n return this.#targetDate.getMilliseconds();\n }\n\n /**\n * 设置年份\n * @param year - 年份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setFullYear(year: number, month?: number, date?: number) {\n this.#targetDate.setFullYear(year);\n this.#updateTimestamp();\n\n if (isNumber(month)) this.setMonth(month);\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置月份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setMonth(month: number, date?: number) {\n this.#targetDate.setMonth(month);\n this.#updateTimestamp();\n\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置日期\n * @param date - 日期\n * @returns 时间戳\n */\n setDate(date: number) {\n this.#targetDate.setDate(date);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 设置小时\n * @param hours - 小时\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setHours(hours: number, minutes?: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setHours(hours);\n this.#updateTimestamp();\n\n if (isNumber(minutes)) this.setMinutes(minutes);\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置分钟\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMinutes(minutes: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setMinutes(minutes);\n this.#updateTimestamp();\n\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置秒数\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setSeconds(seconds: number, milliseconds?: number) {\n this.#targetDate.setSeconds(seconds);\n this.#updateTimestamp();\n\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置毫秒\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMilliseconds(milliseconds: number) {\n this.#targetDate.setMilliseconds(milliseconds);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 获取时间戳\n * @returns 时间戳\n */\n getTime() {\n return this.#timestamp;\n }\n\n /**\n * 获取星期几\n * @returns 星期几 (0-6, 0表示周日)\n */\n getDay() {\n return this.#targetDate.getDay();\n }\n\n /**\n * 转换为 ISO 格式的字符串\n * @returns ISO 格式的时间字符串\n */\n toISOString() {\n return dateFormat(this.#utcDate, 'YYYY-MM-DDTHH:mm:ss.SSSZ');\n }\n\n /**\n * 创建一个 TzDate 对象\n * @param td - 需要转换的日期对象\n * @param offset - 目标时区分钟偏移量,默认为当前时区\n * @returns 返回一个 TzDate 对象\n * @example\n * ```js\n * const tzDate = TzDate.from(new TzDate());\n * ```\n */\n static from(td: TzDate, offset = TzDate.getOffset()) {\n return new TzDate({\n offset: offset,\n timestamp: td.getTime(),\n });\n }\n\n /**\n * 获取时区序号\n * @param offset - 默认使用当前时区分钟偏移量\n * @returns 时区序号\n */\n static getOrder(offset = TzDate.getOffset()) {\n return offset / -60;\n }\n\n /**\n * 获取时区分钟偏移量\n * @param gmtOrder - 默认使用当前时区序号\n * @returns 时区分钟偏移量\n */\n static getOffset(gmtOrder?: number) {\n return isNumber(gmtOrder) ? gmtOrder * -60 : new Date().getTimezoneOffset();\n }\n}\n","import { objectEach } from '@/object';\nimport { isDate, isString } from '@/type';\nimport { TzDate } from './timezone';\n\n/**\n * 判断一个值是否为有效的日期对象\n * @param unknown - 需要判断的值\n * @returns 如果值是有效的日期对象则返回 true,否则返回 false\n * @example\n * ```typescript\n * isValidDate(new Date()); // true\n * isValidDate('2023-01-01'); // false\n * isValidDate(NaN); // false\n * ```\n */\nexport function isValidDate(unknown: unknown): unknown is Date | TzDate {\n return (\n (unknown instanceof Date && !Number.isNaN(unknown.getTime())) ||\n (unknown instanceof TzDate && !Number.isNaN(unknown.getTime()))\n );\n}\n\nexport type DateLike = Date | TzDate;\nexport type DateValue = number | string | DateLike;\n\nfunction _guessDateSeparator(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const value2 = value.replace(/-/g, '/');\n\n return new Date(value2);\n}\n\nfunction _guessDateTimezone(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const re = /([+-])(\\d\\d)(\\d\\d)$/;\n\n const matches = re.exec(value);\n\n if (!matches) return;\n\n const value2 = value.replace(re, 'Z');\n const d = new Date(value2);\n\n if (!isValidDate(d)) return;\n\n const [, flag, hours, minutes] = matches;\n const hours2 = Number.parseInt(hours, 10);\n const minutes2 = Number.parseInt(minutes, 10);\n const offset = (a: number, b: number): number => (flag === '+' ? a - b : a + b);\n\n d.setHours(offset(d.getHours(), hours2));\n d.setMinutes(offset(d.getMinutes(), minutes2));\n\n return d;\n}\n\n/**\n * 解析为Date对象\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 解析后的 Date 对象\n * @throws {SyntaxError} 如果无法解析为有效的日期对象,则抛出错误\n * @example\n * ```typescript\n * dateParse('2023-01-01'); // Date对象\n * dateParse(1672531200000); // Date对象\n * dateParse(new Date()); // Date对象\n * dateParse('invalid date'); // 抛出 SyntaxError\n * ```\n */\nexport function dateParse(dateValue: DateValue): DateLike {\n // 传入的 Date 对象有 Date、TzDate\n // @ts-ignore\n const d1 = isDate(dateValue)\n ? new Date(dateValue)\n : dateValue instanceof TzDate\n ? new TzDate(dateValue)\n : new Date(dateValue);\n if (isValidDate(d1)) return d1;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26 18:06:15') 返回值是一个非法日期对象\n const d2 = _guessDateSeparator(dateValue);\n if (isValidDate(d2)) return d2;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26T18:06:15.000+0800') 返回值是一个非法日期对象\n const d3 = _guessDateTimezone(dateValue);\n if (isValidDate(d3)) return d3;\n\n throw new SyntaxError(`${dateValue.toString()} 不是一个合法的日期值`);\n}\n\nfunction _pad(num: number, len = 2) {\n return `${num}`.padStart(len, '0');\n}\n\nconst rules: [RegExp, (date: DateLike) => number | string][] = [\n [/Y{4}/gi, (date) => date.getFullYear()],\n [/Y{2}/gi, (date) => date.getFullYear() % 100],\n [/M{2}/g, (date) => _pad(date.getMonth() + 1)],\n [/M{1}/g, (date) => date.getMonth() + 1],\n [/D{2}/gi, (date) => _pad(date.getDate())],\n [/D{1}/gi, (date) => date.getDate()],\n [/H{2}/g, (date) => _pad(date.getHours())],\n [/H{1}/g, (date) => date.getHours()],\n [\n /h{2}/g,\n (date) => {\n const h = date.getHours();\n return _pad(h > 12 ? h - 12 : h);\n },\n ],\n [\n /h{1}/g,\n (date) => {\n const h = date.getHours();\n return h > 12 ? h - 12 : h;\n },\n ],\n [/m{2}/g, (date) => _pad(date.getMinutes())],\n [/m{1}/g, (date) => date.getMinutes()],\n [/s{2}/g, (date) => _pad(date.getSeconds())],\n [/s{1}/g, (date) => date.getSeconds()],\n [/S{3}/g, (date) => _pad(date.getMilliseconds(), 3)],\n [/S{2}/g, (date) => _pad(date.getMilliseconds(), 2)],\n [/S{1}/g, (date) => date.getMilliseconds()],\n];\n\n/**\n * 格式化为日期字符串(带自定义格式化模板)\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param format - 模板,默认是 'YYYY-MM-DD HH:mm:ss',模板字符:\n * - YYYY:年\n * - yyyy: 年\n * - MM:月\n * - DD:日\n * - dd: 日\n * - HH:时(24 小时制)\n * - hh:时(12 小时制)\n * - mm:分\n * - ss:秒\n * - SSS:毫秒\n * @returns 格式化后的日期字符串\n * @example\n * ```typescript\n * dateFormat(new Date(), 'YYYY-MM-DD'); // '2023-01-01'\n * dateFormat(1672531200000, 'YYYY/MM/DD HH:mm:ss'); // '2023/01/01 00:00:00'\n * dateFormat('2023-01-01', 'YYYY年MM月DD日'); // '2023年01月01日'\n * ```\n */\nexport function dateFormat(dateValue: DateValue, format = 'YYYY-MM-DD HH:mm:ss'): string {\n const date = dateParse(dateValue);\n let result = format;\n\n for (const rule of rules) {\n result = result.replace(rule[0], String(rule[1](date)));\n }\n\n return result;\n}\n"],"names":["isNumber","timestamp","isString","isDate"],"mappings":"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"}
1
+ {"version":3,"file":"core.cjs","sources":["../src/date/timezone.ts","../src/date/core.ts"],"sourcesContent":["import { isNumber } from '../type';\nimport { dateFormat } from './core';\n\nexport type TimezoneDateOptions = {\n /**\n * 时间戳\n * @default Date.now()\n */\n timestamp?: number;\n\n /**\n * 日期值\n */\n value?: readonly [\n year?: number,\n month?: number,\n day?: number,\n hours?: number,\n minutes?: number,\n seconds?: number,\n milliseconds?: number,\n ];\n\n /**\n * UTC 时区,支持负数和小数,例如:\n * - 8 表示 UTC+8\n * - -12 表示 UTC-12\n * - 0 表示 UTC 时间\n * - 12.5 表示 UTC+12:30\n */\n utcOffset?: number;\n};\n\n/**\n * 时区偏移量毫秒常量(1分钟 = 60 * 1000 毫秒)\n */\nconst TIMEZONE_OFFSET_MS = 60 * 1000;\n\n/**\n * 时区日期类,用于处理不同时区的日期时间\n */\nexport class TimezoneDate {\n /**\n * 内部时间戳\n */\n #timestamp: number;\n\n /**\n * 目标时区的日期对象\n */\n #targetDate: Date;\n\n /**\n * UTC 日期对象\n */\n #utcDate: Date;\n\n /**\n * 本地时区偏移量(分钟)\n */\n #localTimezoneOffset = TimezoneDate.getTimezoneOffset();\n\n /**\n * 本地时区偏移量(毫秒)\n */\n #localTimezoneOffsetMS = this.#localTimezoneOffset * TIMEZONE_OFFSET_MS;\n\n /**\n * 目标时区偏移量(分钟)\n */\n #targetTimezoneOffset = 0;\n\n /**\n * 目标时区偏移量(毫秒)\n */\n #targetTimezoneOffsetMS = 0;\n\n /**\n * 构造函数选项\n */\n #options: TimezoneDateOptions;\n\n /**\n * 构造一个 TimezoneDate 实例\n * @param options - 配置选项\n */\n constructor(options?: TimezoneDateOptions | TimezoneDate) {\n this.#options =\n (options instanceof TimezoneDate\n ? {\n timestamp: options.getTime(),\n utcOffset: options.getUTCOffset(),\n }\n : options) || {};\n const { utcOffset, timestamp, value } = this.#options;\n this.#targetTimezoneOffset = isNumber(utcOffset)\n ? TimezoneDate.getTimezoneOffset(utcOffset)\n : this.#localTimezoneOffset;\n this.#targetTimezoneOffsetMS = this.#targetTimezoneOffset * TIMEZONE_OFFSET_MS;\n\n if (Array.isArray(value) && value.length > 0) {\n const [fullYear, month, day, hours, minutes, seconds, milliseconds] = value;\n const timestamp = Date.UTC(\n fullYear ?? 0,\n month ?? 0,\n day ?? 1,\n hours ?? 0,\n minutes ?? 0,\n seconds ?? 0,\n milliseconds ?? 0,\n );\n\n this.#timestamp = timestamp + this.#targetTimezoneOffsetMS;\n } else {\n this.#timestamp = timestamp || Date.now();\n }\n\n this.#targetDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS - this.#targetTimezoneOffsetMS);\n this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);\n }\n\n /**\n * 更新内部时间戳\n */\n #updateTimestamp() {\n this.#timestamp = this.#targetDate.getTime() + this.#targetTimezoneOffsetMS - this.#localTimezoneOffsetMS;\n this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);\n }\n\n /**\n * 获取时区偏移量(分钟)\n * @returns 时区偏移量\n */\n getTimezoneOffset() {\n return this.#targetTimezoneOffset;\n }\n\n /**\n * 获取时区偏移量(UTC)\n * @returns 时区序号\n */\n getUTCOffset() {\n return TimezoneDate.getUTCOffset(this.#targetTimezoneOffset);\n }\n\n /**\n * 获取年份\n * @returns 年份\n */\n getFullYear() {\n return this.#targetDate.getFullYear();\n }\n\n /**\n * 获取月份\n * @returns 月份 (0-11)\n */\n getMonth() {\n return this.#targetDate.getMonth();\n }\n\n /**\n * 获取日期\n * @returns 日期 (1-31)\n */\n getDate() {\n return this.#targetDate.getDate();\n }\n\n /**\n * 获取小时\n * @returns 小时 (0-23)\n */\n getHours() {\n return this.#targetDate.getHours();\n }\n\n /**\n * 获取分钟\n * @returns 分钟 (0-59)\n */\n getMinutes() {\n return this.#targetDate.getMinutes();\n }\n\n /**\n * 获取秒数\n * @returns 秒数 (0-59)\n */\n getSeconds() {\n return this.#targetDate.getSeconds();\n }\n\n /**\n * 获取毫秒\n * @returns 毫秒 (0-999)\n */\n getMilliseconds() {\n return this.#targetDate.getMilliseconds();\n }\n\n /**\n * 设置年份\n * @param year - 年份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setFullYear(year: number, month?: number, date?: number) {\n this.#targetDate.setFullYear(year);\n this.#updateTimestamp();\n\n if (isNumber(month)) this.setMonth(month);\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置月份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setMonth(month: number, date?: number) {\n this.#targetDate.setMonth(month);\n this.#updateTimestamp();\n\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置日期\n * @param date - 日期\n * @returns 时间戳\n */\n setDate(date: number) {\n this.#targetDate.setDate(date);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 设置小时\n * @param hours - 小时\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setHours(hours: number, minutes?: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setHours(hours);\n this.#updateTimestamp();\n\n if (isNumber(minutes)) this.setMinutes(minutes);\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置分钟\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMinutes(minutes: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setMinutes(minutes);\n this.#updateTimestamp();\n\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置秒数\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setSeconds(seconds: number, milliseconds?: number) {\n this.#targetDate.setSeconds(seconds);\n this.#updateTimestamp();\n\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置毫秒\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMilliseconds(milliseconds: number) {\n this.#targetDate.setMilliseconds(milliseconds);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 获取时间戳\n * @returns 时间戳\n */\n getTime() {\n return this.#timestamp;\n }\n\n /**\n * 获取星期几\n * @returns 星期几 (0-6, 0表示周日)\n */\n getDay() {\n return this.#targetDate.getDay();\n }\n\n /**\n * 转换为 ISO 格式的字符串\n * @returns ISO 格式的时间字符串\n */\n toISOString() {\n return dateFormat(this.#utcDate, 'YYYY-MM-DDTHH:mm:ss.SSSZ');\n }\n\n /**\n * 转换为指定时区的 TimezoneDate 对象\n * @param td - 需要转换的日期对象\n * @param offset - 目标时区分钟偏移量,默认为当前时区\n * @returns 返回一个 TimezoneDate 对象\n * @example\n * ```js\n * // 转换为 UTC 时间\n * const utc0Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 0);\n *\n * // 转换为东八区时间\n * const utc8Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 8);\n * ```\n */\n static changeUtcOffset(td: TimezoneDate, utcOffset: number) {\n return new TimezoneDate({\n utcOffset,\n timestamp: td.getTime(),\n });\n }\n\n /**\n * 获取时区分钟偏移量\n * @param utcOffset - 默认使用当前时区\n * @returns 时区分钟偏移量\n */\n static getTimezoneOffset(utcOffset?: number) {\n return isNumber(utcOffset) ? utcOffset * -60 : new Date().getTimezoneOffset();\n }\n\n /**\n * 获取时区序号\n * @param timezoneOffset - 默认使用当前时区分钟偏移量\n * @returns 时区序号\n */\n static getUTCOffset(timezoneOffset = TimezoneDate.getTimezoneOffset()) {\n return timezoneOffset / -60;\n }\n}\n","import { objectEach } from '@/object';\nimport { isDate, isString } from '@/type';\nimport { TimezoneDate } from './timezone';\n\n/**\n * 判断一个值是否为有效的日期对象\n * @param unknown - 需要判断的值\n * @returns 如果值是有效的日期对象则返回 true,否则返回 false\n * @example\n * ```typescript\n * isValidDate(new Date()); // true\n * isValidDate('2023-01-01'); // false\n * isValidDate(NaN); // false\n * ```\n */\nexport function isValidDate(unknown: unknown): unknown is Date | TimezoneDate {\n return (\n (unknown instanceof Date && !Number.isNaN(unknown.getTime())) ||\n (unknown instanceof TimezoneDate && !Number.isNaN(unknown.getTime()))\n );\n}\n\nexport type DateLike = Date | TimezoneDate;\nexport type DateValue = number | string | DateLike;\n\nfunction _guessDateSeparator(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const value2 = value.replace(/-/g, '/');\n\n return new Date(value2);\n}\n\nfunction _guessDateTimezone(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const re = /([+-])(\\d\\d)(\\d\\d)$/;\n\n const matches = re.exec(value);\n\n if (!matches) return;\n\n const value2 = value.replace(re, 'Z');\n const d = new Date(value2);\n\n if (!isValidDate(d)) return;\n\n const [, flag, hours, minutes] = matches;\n const hours2 = Number.parseInt(hours, 10);\n const minutes2 = Number.parseInt(minutes, 10);\n const offset = (a: number, b: number): number => (flag === '+' ? a - b : a + b);\n\n d.setHours(offset(d.getHours(), hours2));\n d.setMinutes(offset(d.getMinutes(), minutes2));\n\n return d;\n}\n\n/**\n * 解析为Date对象\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 解析后的 Date 对象\n * @throws {SyntaxError} 如果无法解析为有效的日期对象,则抛出错误\n * @example\n * ```typescript\n * dateParse('2023-01-01'); // Date对象\n * dateParse(1672531200000); // Date对象\n * dateParse(new Date()); // Date对象\n * dateParse('invalid date'); // 抛出 SyntaxError\n * ```\n */\nexport function dateParse(dateValue: DateValue): DateLike {\n // 传入的 Date 对象有 Date、TimezoneDate\n // @ts-ignore\n const d1 = isDate(dateValue)\n ? new Date(dateValue)\n : dateValue instanceof TimezoneDate\n ? new TimezoneDate(dateValue)\n : new Date(dateValue);\n if (isValidDate(d1)) return d1;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26 18:06:15') 返回值是一个非法日期对象\n const d2 = _guessDateSeparator(dateValue);\n if (isValidDate(d2)) return d2;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26T18:06:15.000+0800') 返回值是一个非法日期对象\n const d3 = _guessDateTimezone(dateValue);\n if (isValidDate(d3)) return d3;\n\n throw new SyntaxError(`${dateValue.toString()} 不是一个合法的日期值`);\n}\n\nfunction _pad(num: number, len = 2) {\n return `${num}`.padStart(len, '0');\n}\n\nconst rules: [RegExp, (date: DateLike) => number | string][] = [\n [/Y{4}/gi, (date) => date.getFullYear()],\n [/Y{2}/gi, (date) => date.getFullYear() % 100],\n [/M{2}/g, (date) => _pad(date.getMonth() + 1)],\n [/M{1}/g, (date) => date.getMonth() + 1],\n [/D{2}/gi, (date) => _pad(date.getDate())],\n [/D{1}/gi, (date) => date.getDate()],\n [/H{2}/g, (date) => _pad(date.getHours())],\n [/H{1}/g, (date) => date.getHours()],\n [\n /h{2}/g,\n (date) => {\n const h = date.getHours();\n return _pad(h > 12 ? h - 12 : h);\n },\n ],\n [\n /h{1}/g,\n (date) => {\n const h = date.getHours();\n return h > 12 ? h - 12 : h;\n },\n ],\n [/m{2}/g, (date) => _pad(date.getMinutes())],\n [/m{1}/g, (date) => date.getMinutes()],\n [/s{2}/g, (date) => _pad(date.getSeconds())],\n [/s{1}/g, (date) => date.getSeconds()],\n [/S{3}/g, (date) => _pad(date.getMilliseconds(), 3)],\n [/S{2}/g, (date) => _pad(date.getMilliseconds(), 2)],\n [/S{1}/g, (date) => date.getMilliseconds()],\n];\n\n/**\n * 格式化为日期字符串(带自定义格式化模板)\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param format - 模板,默认是 'YYYY-MM-DD HH:mm:ss',模板字符:\n * - YYYY:年\n * - yyyy: 年\n * - MM:月\n * - DD:日\n * - dd: 日\n * - HH:时(24 小时制)\n * - hh:时(12 小时制)\n * - mm:分\n * - ss:秒\n * - SSS:毫秒\n * @returns 格式化后的日期字符串\n * @example\n * ```typescript\n * dateFormat(new Date(), 'YYYY-MM-DD'); // '2023-01-01'\n * dateFormat(1672531200000, 'YYYY/MM/DD HH:mm:ss'); // '2023/01/01 00:00:00'\n * dateFormat('2023-01-01', 'YYYY年MM月DD日'); // '2023年01月01日'\n * ```\n */\nexport function dateFormat(dateValue: DateValue, format = 'YYYY-MM-DD HH:mm:ss'): string {\n const date = dateParse(dateValue);\n let result = format;\n\n for (const rule of rules) {\n result = result.replace(rule[0], String(rule[1](date)));\n }\n\n return result;\n}\n"],"names":["isNumber","timestamp","isString","isDate"],"mappings":"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"}
package/dist/core.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { isNumber, isDate, isString } from "./type.mjs";
2
- const TZ_OFFSET_MS = 60 * 1e3;
3
- class TzDate {
2
+ const TIMEZONE_OFFSET_MS = 60 * 1e3;
3
+ class TimezoneDate {
4
4
  /**
5
5
  * 内部时间戳
6
6
  */
@@ -16,35 +16,35 @@ class TzDate {
16
16
  /**
17
17
  * 本地时区偏移量(分钟)
18
18
  */
19
- #localTZOffset = TzDate.getOffset();
19
+ #localTimezoneOffset = TimezoneDate.getTimezoneOffset();
20
20
  /**
21
21
  * 本地时区偏移量(毫秒)
22
22
  */
23
- #localTzOffsetMS = this.#localTZOffset * TZ_OFFSET_MS;
23
+ #localTimezoneOffsetMS = this.#localTimezoneOffset * TIMEZONE_OFFSET_MS;
24
24
  /**
25
25
  * 目标时区偏移量(分钟)
26
26
  */
27
- #targetTzOffset = 0;
27
+ #targetTimezoneOffset = 0;
28
28
  /**
29
29
  * 目标时区偏移量(毫秒)
30
30
  */
31
- #targetTzOffsetMS = 0;
31
+ #targetTimezoneOffsetMS = 0;
32
32
  /**
33
33
  * 构造函数选项
34
34
  */
35
35
  #options;
36
36
  /**
37
- * 构造一个 TzDate 实例
37
+ * 构造一个 TimezoneDate 实例
38
38
  * @param options - 配置选项
39
39
  */
40
40
  constructor(options) {
41
- this.#options = (options instanceof TzDate ? {
41
+ this.#options = (options instanceof TimezoneDate ? {
42
42
  timestamp: options.getTime(),
43
- offset: options.getTimezoneOffset()
43
+ utcOffset: options.getUTCOffset()
44
44
  } : options) || {};
45
- const { offset, timestamp, value } = this.#options;
46
- this.#targetTzOffset = isNumber(offset) ? offset : this.#localTZOffset;
47
- this.#targetTzOffsetMS = this.#targetTzOffset * TZ_OFFSET_MS;
45
+ const { utcOffset, timestamp, value } = this.#options;
46
+ this.#targetTimezoneOffset = isNumber(utcOffset) ? TimezoneDate.getTimezoneOffset(utcOffset) : this.#localTimezoneOffset;
47
+ this.#targetTimezoneOffsetMS = this.#targetTimezoneOffset * TIMEZONE_OFFSET_MS;
48
48
  if (Array.isArray(value) && value.length > 0) {
49
49
  const [fullYear, month, day, hours, minutes, seconds, milliseconds] = value;
50
50
  const timestamp2 = Date.UTC(
@@ -56,33 +56,33 @@ class TzDate {
56
56
  seconds ?? 0,
57
57
  milliseconds ?? 0
58
58
  );
59
- this.#timestamp = timestamp2 + this.#targetTzOffsetMS;
59
+ this.#timestamp = timestamp2 + this.#targetTimezoneOffsetMS;
60
60
  } else {
61
61
  this.#timestamp = timestamp || Date.now();
62
62
  }
63
- this.#targetDate = new Date(this.#timestamp + this.#localTzOffsetMS - this.#targetTzOffsetMS);
64
- this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);
63
+ this.#targetDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS - this.#targetTimezoneOffsetMS);
64
+ this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);
65
65
  }
66
66
  /**
67
67
  * 更新内部时间戳
68
68
  */
69
69
  #updateTimestamp() {
70
- this.#timestamp = this.#targetDate.getTime() + this.#targetTzOffsetMS - this.#localTzOffsetMS;
71
- this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);
70
+ this.#timestamp = this.#targetDate.getTime() + this.#targetTimezoneOffsetMS - this.#localTimezoneOffsetMS;
71
+ this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);
72
72
  }
73
73
  /**
74
74
  * 获取时区偏移量(分钟)
75
75
  * @returns 时区偏移量
76
76
  */
77
77
  getTimezoneOffset() {
78
- return this.#targetTzOffset;
78
+ return this.#targetTimezoneOffset;
79
79
  }
80
80
  /**
81
- * 获取时区序号
81
+ * 获取时区偏移量(UTC)
82
82
  * @returns 时区序号
83
83
  */
84
- getTimezoneOrder() {
85
- return TzDate.getOrder(this.#targetTzOffset);
84
+ getUTCOffset() {
85
+ return TimezoneDate.getUTCOffset(this.#targetTimezoneOffset);
86
86
  }
87
87
  /**
88
88
  * 获取年份
@@ -243,40 +243,44 @@ class TzDate {
243
243
  return dateFormat(this.#utcDate, "YYYY-MM-DDTHH:mm:ss.SSSZ");
244
244
  }
245
245
  /**
246
- * 创建一个 TzDate 对象
246
+ * 转换为指定时区的 TimezoneDate 对象
247
247
  * @param td - 需要转换的日期对象
248
248
  * @param offset - 目标时区分钟偏移量,默认为当前时区
249
- * @returns 返回一个 TzDate 对象
249
+ * @returns 返回一个 TimezoneDate 对象
250
250
  * @example
251
251
  * ```js
252
- * const tzDate = TzDate.from(new TzDate());
252
+ * // 转换为 UTC 时间
253
+ * const utc0Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 0);
254
+ *
255
+ * // 转换为东八区时间
256
+ * const utc8Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 8);
253
257
  * ```
254
258
  */
255
- static from(td, offset = TzDate.getOffset()) {
256
- return new TzDate({
257
- offset,
259
+ static changeUtcOffset(td, utcOffset) {
260
+ return new TimezoneDate({
261
+ utcOffset,
258
262
  timestamp: td.getTime()
259
263
  });
260
264
  }
261
265
  /**
262
- * 获取时区序号
263
- * @param offset - 默认使用当前时区分钟偏移量
264
- * @returns 时区序号
266
+ * 获取时区分钟偏移量
267
+ * @param utcOffset - 默认使用当前时区
268
+ * @returns 时区分钟偏移量
265
269
  */
266
- static getOrder(offset = TzDate.getOffset()) {
267
- return offset / -60;
270
+ static getTimezoneOffset(utcOffset) {
271
+ return isNumber(utcOffset) ? utcOffset * -60 : (/* @__PURE__ */ new Date()).getTimezoneOffset();
268
272
  }
269
273
  /**
270
- * 获取时区分钟偏移量
271
- * @param gmtOrder - 默认使用当前时区序号
272
- * @returns 时区分钟偏移量
274
+ * 获取时区序号
275
+ * @param timezoneOffset - 默认使用当前时区分钟偏移量
276
+ * @returns 时区序号
273
277
  */
274
- static getOffset(gmtOrder) {
275
- return isNumber(gmtOrder) ? gmtOrder * -60 : (/* @__PURE__ */ new Date()).getTimezoneOffset();
278
+ static getUTCOffset(timezoneOffset = TimezoneDate.getTimezoneOffset()) {
279
+ return timezoneOffset / -60;
276
280
  }
277
281
  }
278
282
  function isValidDate(unknown) {
279
- return unknown instanceof Date && !Number.isNaN(unknown.getTime()) || unknown instanceof TzDate && !Number.isNaN(unknown.getTime());
283
+ return unknown instanceof Date && !Number.isNaN(unknown.getTime()) || unknown instanceof TimezoneDate && !Number.isNaN(unknown.getTime());
280
284
  }
281
285
  function _guessDateSeparator(value) {
282
286
  if (!isString(value)) return;
@@ -300,7 +304,7 @@ function _guessDateTimezone(value) {
300
304
  return d;
301
305
  }
302
306
  function dateParse(dateValue) {
303
- const d1 = isDate(dateValue) ? new Date(dateValue) : dateValue instanceof TzDate ? new TzDate(dateValue) : new Date(dateValue);
307
+ const d1 = isDate(dateValue) ? new Date(dateValue) : dateValue instanceof TimezoneDate ? new TimezoneDate(dateValue) : new Date(dateValue);
304
308
  if (isValidDate(d1)) return d1;
305
309
  const d2 = _guessDateSeparator(dateValue);
306
310
  if (isValidDate(d2)) return d2;
@@ -351,7 +355,7 @@ function dateFormat(dateValue, format = "YYYY-MM-DD HH:mm:ss") {
351
355
  return result;
352
356
  }
353
357
  export {
354
- TzDate as T,
358
+ TimezoneDate as T,
355
359
  dateFormat as a,
356
360
  dateParse as d,
357
361
  isValidDate as i
package/dist/core.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.mjs","sources":["../src/date/timezone.ts","../src/date/core.ts"],"sourcesContent":["import { isNumber } from '../type';\nimport { dateFormat } from './core';\n\nexport type TzDateOptions = {\n /**\n * 时间戳\n * @default Date.now()\n */\n timestamp?: number;\n\n /**\n * 日期值\n */\n value?: readonly [\n year?: number,\n month?: number,\n day?: number,\n hours?: number,\n minutes?: number,\n seconds?: number,\n milliseconds?: number,\n ];\n\n /**\n * 时区偏移量,单位为分钟,默认为当前时区\n */\n offset?: number;\n};\n\n/**\n * 时区偏移量毫秒常量(1分钟 = 60 * 1000 毫秒)\n */\nconst TZ_OFFSET_MS = 60 * 1000;\n\n/**\n * 时区日期类,用于处理不同时区的日期时间\n */\nexport class TzDate {\n /**\n * 内部时间戳\n */\n #timestamp: number;\n\n /**\n * 目标时区的日期对象\n */\n #targetDate: Date;\n\n /**\n * UTC 日期对象\n */\n #utcDate: Date;\n\n /**\n * 本地时区偏移量(分钟)\n */\n #localTZOffset = TzDate.getOffset();\n\n /**\n * 本地时区偏移量(毫秒)\n */\n #localTzOffsetMS = this.#localTZOffset * TZ_OFFSET_MS;\n\n /**\n * 目标时区偏移量(分钟)\n */\n #targetTzOffset = 0;\n\n /**\n * 目标时区偏移量(毫秒)\n */\n #targetTzOffsetMS = 0;\n\n /**\n * 构造函数选项\n */\n #options: TzDateOptions;\n\n /**\n * 构造一个 TzDate 实例\n * @param options - 配置选项\n */\n constructor(options?: TzDateOptions | TzDate) {\n this.#options =\n (options instanceof TzDate\n ? {\n timestamp: options.getTime(),\n offset: options.getTimezoneOffset(),\n }\n : options) || {};\n const { offset, timestamp, value } = this.#options;\n this.#targetTzOffset = isNumber(offset) ? offset : this.#localTZOffset;\n this.#targetTzOffsetMS = this.#targetTzOffset * TZ_OFFSET_MS;\n\n if (Array.isArray(value) && value.length > 0) {\n const [fullYear, month, day, hours, minutes, seconds, milliseconds] = value;\n const timestamp = Date.UTC(\n fullYear ?? 0,\n month ?? 0,\n day ?? 1,\n hours ?? 0,\n minutes ?? 0,\n seconds ?? 0,\n milliseconds ?? 0,\n );\n\n this.#timestamp = timestamp + this.#targetTzOffsetMS;\n } else {\n this.#timestamp = timestamp || Date.now();\n }\n\n this.#targetDate = new Date(this.#timestamp + this.#localTzOffsetMS - this.#targetTzOffsetMS);\n this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);\n }\n\n /**\n * 更新内部时间戳\n */\n #updateTimestamp() {\n this.#timestamp = this.#targetDate.getTime() + this.#targetTzOffsetMS - this.#localTzOffsetMS;\n this.#utcDate = new Date(this.#timestamp + this.#localTzOffsetMS);\n }\n\n /**\n * 获取时区偏移量(分钟)\n * @returns 时区偏移量\n */\n getTimezoneOffset() {\n return this.#targetTzOffset;\n }\n\n /**\n * 获取时区序号\n * @returns 时区序号\n */\n getTimezoneOrder() {\n return TzDate.getOrder(this.#targetTzOffset);\n }\n\n /**\n * 获取年份\n * @returns 年份\n */\n getFullYear() {\n return this.#targetDate.getFullYear();\n }\n\n /**\n * 获取月份\n * @returns 月份 (0-11)\n */\n getMonth() {\n return this.#targetDate.getMonth();\n }\n\n /**\n * 获取日期\n * @returns 日期 (1-31)\n */\n getDate() {\n return this.#targetDate.getDate();\n }\n\n /**\n * 获取小时\n * @returns 小时 (0-23)\n */\n getHours() {\n return this.#targetDate.getHours();\n }\n\n /**\n * 获取分钟\n * @returns 分钟 (0-59)\n */\n getMinutes() {\n return this.#targetDate.getMinutes();\n }\n\n /**\n * 获取秒数\n * @returns 秒数 (0-59)\n */\n getSeconds() {\n return this.#targetDate.getSeconds();\n }\n\n /**\n * 获取毫秒\n * @returns 毫秒 (0-999)\n */\n getMilliseconds() {\n return this.#targetDate.getMilliseconds();\n }\n\n /**\n * 设置年份\n * @param year - 年份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setFullYear(year: number, month?: number, date?: number) {\n this.#targetDate.setFullYear(year);\n this.#updateTimestamp();\n\n if (isNumber(month)) this.setMonth(month);\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置月份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setMonth(month: number, date?: number) {\n this.#targetDate.setMonth(month);\n this.#updateTimestamp();\n\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置日期\n * @param date - 日期\n * @returns 时间戳\n */\n setDate(date: number) {\n this.#targetDate.setDate(date);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 设置小时\n * @param hours - 小时\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setHours(hours: number, minutes?: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setHours(hours);\n this.#updateTimestamp();\n\n if (isNumber(minutes)) this.setMinutes(minutes);\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置分钟\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMinutes(minutes: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setMinutes(minutes);\n this.#updateTimestamp();\n\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置秒数\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setSeconds(seconds: number, milliseconds?: number) {\n this.#targetDate.setSeconds(seconds);\n this.#updateTimestamp();\n\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置毫秒\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMilliseconds(milliseconds: number) {\n this.#targetDate.setMilliseconds(milliseconds);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 获取时间戳\n * @returns 时间戳\n */\n getTime() {\n return this.#timestamp;\n }\n\n /**\n * 获取星期几\n * @returns 星期几 (0-6, 0表示周日)\n */\n getDay() {\n return this.#targetDate.getDay();\n }\n\n /**\n * 转换为 ISO 格式的字符串\n * @returns ISO 格式的时间字符串\n */\n toISOString() {\n return dateFormat(this.#utcDate, 'YYYY-MM-DDTHH:mm:ss.SSSZ');\n }\n\n /**\n * 创建一个 TzDate 对象\n * @param td - 需要转换的日期对象\n * @param offset - 目标时区分钟偏移量,默认为当前时区\n * @returns 返回一个 TzDate 对象\n * @example\n * ```js\n * const tzDate = TzDate.from(new TzDate());\n * ```\n */\n static from(td: TzDate, offset = TzDate.getOffset()) {\n return new TzDate({\n offset: offset,\n timestamp: td.getTime(),\n });\n }\n\n /**\n * 获取时区序号\n * @param offset - 默认使用当前时区分钟偏移量\n * @returns 时区序号\n */\n static getOrder(offset = TzDate.getOffset()) {\n return offset / -60;\n }\n\n /**\n * 获取时区分钟偏移量\n * @param gmtOrder - 默认使用当前时区序号\n * @returns 时区分钟偏移量\n */\n static getOffset(gmtOrder?: number) {\n return isNumber(gmtOrder) ? gmtOrder * -60 : new Date().getTimezoneOffset();\n }\n}\n","import { objectEach } from '@/object';\nimport { isDate, isString } from '@/type';\nimport { TzDate } from './timezone';\n\n/**\n * 判断一个值是否为有效的日期对象\n * @param unknown - 需要判断的值\n * @returns 如果值是有效的日期对象则返回 true,否则返回 false\n * @example\n * ```typescript\n * isValidDate(new Date()); // true\n * isValidDate('2023-01-01'); // false\n * isValidDate(NaN); // false\n * ```\n */\nexport function isValidDate(unknown: unknown): unknown is Date | TzDate {\n return (\n (unknown instanceof Date && !Number.isNaN(unknown.getTime())) ||\n (unknown instanceof TzDate && !Number.isNaN(unknown.getTime()))\n );\n}\n\nexport type DateLike = Date | TzDate;\nexport type DateValue = number | string | DateLike;\n\nfunction _guessDateSeparator(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const value2 = value.replace(/-/g, '/');\n\n return new Date(value2);\n}\n\nfunction _guessDateTimezone(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const re = /([+-])(\\d\\d)(\\d\\d)$/;\n\n const matches = re.exec(value);\n\n if (!matches) return;\n\n const value2 = value.replace(re, 'Z');\n const d = new Date(value2);\n\n if (!isValidDate(d)) return;\n\n const [, flag, hours, minutes] = matches;\n const hours2 = Number.parseInt(hours, 10);\n const minutes2 = Number.parseInt(minutes, 10);\n const offset = (a: number, b: number): number => (flag === '+' ? a - b : a + b);\n\n d.setHours(offset(d.getHours(), hours2));\n d.setMinutes(offset(d.getMinutes(), minutes2));\n\n return d;\n}\n\n/**\n * 解析为Date对象\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 解析后的 Date 对象\n * @throws {SyntaxError} 如果无法解析为有效的日期对象,则抛出错误\n * @example\n * ```typescript\n * dateParse('2023-01-01'); // Date对象\n * dateParse(1672531200000); // Date对象\n * dateParse(new Date()); // Date对象\n * dateParse('invalid date'); // 抛出 SyntaxError\n * ```\n */\nexport function dateParse(dateValue: DateValue): DateLike {\n // 传入的 Date 对象有 Date、TzDate\n // @ts-ignore\n const d1 = isDate(dateValue)\n ? new Date(dateValue)\n : dateValue instanceof TzDate\n ? new TzDate(dateValue)\n : new Date(dateValue);\n if (isValidDate(d1)) return d1;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26 18:06:15') 返回值是一个非法日期对象\n const d2 = _guessDateSeparator(dateValue);\n if (isValidDate(d2)) return d2;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26T18:06:15.000+0800') 返回值是一个非法日期对象\n const d3 = _guessDateTimezone(dateValue);\n if (isValidDate(d3)) return d3;\n\n throw new SyntaxError(`${dateValue.toString()} 不是一个合法的日期值`);\n}\n\nfunction _pad(num: number, len = 2) {\n return `${num}`.padStart(len, '0');\n}\n\nconst rules: [RegExp, (date: DateLike) => number | string][] = [\n [/Y{4}/gi, (date) => date.getFullYear()],\n [/Y{2}/gi, (date) => date.getFullYear() % 100],\n [/M{2}/g, (date) => _pad(date.getMonth() + 1)],\n [/M{1}/g, (date) => date.getMonth() + 1],\n [/D{2}/gi, (date) => _pad(date.getDate())],\n [/D{1}/gi, (date) => date.getDate()],\n [/H{2}/g, (date) => _pad(date.getHours())],\n [/H{1}/g, (date) => date.getHours()],\n [\n /h{2}/g,\n (date) => {\n const h = date.getHours();\n return _pad(h > 12 ? h - 12 : h);\n },\n ],\n [\n /h{1}/g,\n (date) => {\n const h = date.getHours();\n return h > 12 ? h - 12 : h;\n },\n ],\n [/m{2}/g, (date) => _pad(date.getMinutes())],\n [/m{1}/g, (date) => date.getMinutes()],\n [/s{2}/g, (date) => _pad(date.getSeconds())],\n [/s{1}/g, (date) => date.getSeconds()],\n [/S{3}/g, (date) => _pad(date.getMilliseconds(), 3)],\n [/S{2}/g, (date) => _pad(date.getMilliseconds(), 2)],\n [/S{1}/g, (date) => date.getMilliseconds()],\n];\n\n/**\n * 格式化为日期字符串(带自定义格式化模板)\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param format - 模板,默认是 'YYYY-MM-DD HH:mm:ss',模板字符:\n * - YYYY:年\n * - yyyy: 年\n * - MM:月\n * - DD:日\n * - dd: 日\n * - HH:时(24 小时制)\n * - hh:时(12 小时制)\n * - mm:分\n * - ss:秒\n * - SSS:毫秒\n * @returns 格式化后的日期字符串\n * @example\n * ```typescript\n * dateFormat(new Date(), 'YYYY-MM-DD'); // '2023-01-01'\n * dateFormat(1672531200000, 'YYYY/MM/DD HH:mm:ss'); // '2023/01/01 00:00:00'\n * dateFormat('2023-01-01', 'YYYY年MM月DD日'); // '2023年01月01日'\n * ```\n */\nexport function dateFormat(dateValue: DateValue, format = 'YYYY-MM-DD HH:mm:ss'): string {\n const date = dateParse(dateValue);\n let result = format;\n\n for (const rule of rules) {\n result = result.replace(rule[0], String(rule[1](date)));\n }\n\n return result;\n}\n"],"names":["timestamp"],"mappings":"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"}
1
+ {"version":3,"file":"core.mjs","sources":["../src/date/timezone.ts","../src/date/core.ts"],"sourcesContent":["import { isNumber } from '../type';\nimport { dateFormat } from './core';\n\nexport type TimezoneDateOptions = {\n /**\n * 时间戳\n * @default Date.now()\n */\n timestamp?: number;\n\n /**\n * 日期值\n */\n value?: readonly [\n year?: number,\n month?: number,\n day?: number,\n hours?: number,\n minutes?: number,\n seconds?: number,\n milliseconds?: number,\n ];\n\n /**\n * UTC 时区,支持负数和小数,例如:\n * - 8 表示 UTC+8\n * - -12 表示 UTC-12\n * - 0 表示 UTC 时间\n * - 12.5 表示 UTC+12:30\n */\n utcOffset?: number;\n};\n\n/**\n * 时区偏移量毫秒常量(1分钟 = 60 * 1000 毫秒)\n */\nconst TIMEZONE_OFFSET_MS = 60 * 1000;\n\n/**\n * 时区日期类,用于处理不同时区的日期时间\n */\nexport class TimezoneDate {\n /**\n * 内部时间戳\n */\n #timestamp: number;\n\n /**\n * 目标时区的日期对象\n */\n #targetDate: Date;\n\n /**\n * UTC 日期对象\n */\n #utcDate: Date;\n\n /**\n * 本地时区偏移量(分钟)\n */\n #localTimezoneOffset = TimezoneDate.getTimezoneOffset();\n\n /**\n * 本地时区偏移量(毫秒)\n */\n #localTimezoneOffsetMS = this.#localTimezoneOffset * TIMEZONE_OFFSET_MS;\n\n /**\n * 目标时区偏移量(分钟)\n */\n #targetTimezoneOffset = 0;\n\n /**\n * 目标时区偏移量(毫秒)\n */\n #targetTimezoneOffsetMS = 0;\n\n /**\n * 构造函数选项\n */\n #options: TimezoneDateOptions;\n\n /**\n * 构造一个 TimezoneDate 实例\n * @param options - 配置选项\n */\n constructor(options?: TimezoneDateOptions | TimezoneDate) {\n this.#options =\n (options instanceof TimezoneDate\n ? {\n timestamp: options.getTime(),\n utcOffset: options.getUTCOffset(),\n }\n : options) || {};\n const { utcOffset, timestamp, value } = this.#options;\n this.#targetTimezoneOffset = isNumber(utcOffset)\n ? TimezoneDate.getTimezoneOffset(utcOffset)\n : this.#localTimezoneOffset;\n this.#targetTimezoneOffsetMS = this.#targetTimezoneOffset * TIMEZONE_OFFSET_MS;\n\n if (Array.isArray(value) && value.length > 0) {\n const [fullYear, month, day, hours, minutes, seconds, milliseconds] = value;\n const timestamp = Date.UTC(\n fullYear ?? 0,\n month ?? 0,\n day ?? 1,\n hours ?? 0,\n minutes ?? 0,\n seconds ?? 0,\n milliseconds ?? 0,\n );\n\n this.#timestamp = timestamp + this.#targetTimezoneOffsetMS;\n } else {\n this.#timestamp = timestamp || Date.now();\n }\n\n this.#targetDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS - this.#targetTimezoneOffsetMS);\n this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);\n }\n\n /**\n * 更新内部时间戳\n */\n #updateTimestamp() {\n this.#timestamp = this.#targetDate.getTime() + this.#targetTimezoneOffsetMS - this.#localTimezoneOffsetMS;\n this.#utcDate = new Date(this.#timestamp + this.#localTimezoneOffsetMS);\n }\n\n /**\n * 获取时区偏移量(分钟)\n * @returns 时区偏移量\n */\n getTimezoneOffset() {\n return this.#targetTimezoneOffset;\n }\n\n /**\n * 获取时区偏移量(UTC)\n * @returns 时区序号\n */\n getUTCOffset() {\n return TimezoneDate.getUTCOffset(this.#targetTimezoneOffset);\n }\n\n /**\n * 获取年份\n * @returns 年份\n */\n getFullYear() {\n return this.#targetDate.getFullYear();\n }\n\n /**\n * 获取月份\n * @returns 月份 (0-11)\n */\n getMonth() {\n return this.#targetDate.getMonth();\n }\n\n /**\n * 获取日期\n * @returns 日期 (1-31)\n */\n getDate() {\n return this.#targetDate.getDate();\n }\n\n /**\n * 获取小时\n * @returns 小时 (0-23)\n */\n getHours() {\n return this.#targetDate.getHours();\n }\n\n /**\n * 获取分钟\n * @returns 分钟 (0-59)\n */\n getMinutes() {\n return this.#targetDate.getMinutes();\n }\n\n /**\n * 获取秒数\n * @returns 秒数 (0-59)\n */\n getSeconds() {\n return this.#targetDate.getSeconds();\n }\n\n /**\n * 获取毫秒\n * @returns 毫秒 (0-999)\n */\n getMilliseconds() {\n return this.#targetDate.getMilliseconds();\n }\n\n /**\n * 设置年份\n * @param year - 年份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setFullYear(year: number, month?: number, date?: number) {\n this.#targetDate.setFullYear(year);\n this.#updateTimestamp();\n\n if (isNumber(month)) this.setMonth(month);\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置月份\n * @param month - 月份\n * @param date - 日期\n * @returns 时间戳\n */\n setMonth(month: number, date?: number) {\n this.#targetDate.setMonth(month);\n this.#updateTimestamp();\n\n if (isNumber(date)) this.setDate(date);\n\n return this.getTime();\n }\n\n /**\n * 设置日期\n * @param date - 日期\n * @returns 时间戳\n */\n setDate(date: number) {\n this.#targetDate.setDate(date);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 设置小时\n * @param hours - 小时\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setHours(hours: number, minutes?: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setHours(hours);\n this.#updateTimestamp();\n\n if (isNumber(minutes)) this.setMinutes(minutes);\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置分钟\n * @param minutes - 分钟\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMinutes(minutes: number, seconds?: number, milliseconds?: number) {\n this.#targetDate.setMinutes(minutes);\n this.#updateTimestamp();\n\n if (isNumber(seconds)) this.setSeconds(seconds);\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置秒数\n * @param seconds - 秒数\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setSeconds(seconds: number, milliseconds?: number) {\n this.#targetDate.setSeconds(seconds);\n this.#updateTimestamp();\n\n if (isNumber(milliseconds)) this.setMilliseconds(milliseconds);\n\n return this.getTime();\n }\n\n /**\n * 设置毫秒\n * @param milliseconds - 毫秒\n * @returns 时间戳\n */\n setMilliseconds(milliseconds: number) {\n this.#targetDate.setMilliseconds(milliseconds);\n this.#updateTimestamp();\n\n return this.getTime();\n }\n\n /**\n * 获取时间戳\n * @returns 时间戳\n */\n getTime() {\n return this.#timestamp;\n }\n\n /**\n * 获取星期几\n * @returns 星期几 (0-6, 0表示周日)\n */\n getDay() {\n return this.#targetDate.getDay();\n }\n\n /**\n * 转换为 ISO 格式的字符串\n * @returns ISO 格式的时间字符串\n */\n toISOString() {\n return dateFormat(this.#utcDate, 'YYYY-MM-DDTHH:mm:ss.SSSZ');\n }\n\n /**\n * 转换为指定时区的 TimezoneDate 对象\n * @param td - 需要转换的日期对象\n * @param offset - 目标时区分钟偏移量,默认为当前时区\n * @returns 返回一个 TimezoneDate 对象\n * @example\n * ```js\n * // 转换为 UTC 时间\n * const utc0Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 0);\n *\n * // 转换为东八区时间\n * const utc8Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 8);\n * ```\n */\n static changeUtcOffset(td: TimezoneDate, utcOffset: number) {\n return new TimezoneDate({\n utcOffset,\n timestamp: td.getTime(),\n });\n }\n\n /**\n * 获取时区分钟偏移量\n * @param utcOffset - 默认使用当前时区\n * @returns 时区分钟偏移量\n */\n static getTimezoneOffset(utcOffset?: number) {\n return isNumber(utcOffset) ? utcOffset * -60 : new Date().getTimezoneOffset();\n }\n\n /**\n * 获取时区序号\n * @param timezoneOffset - 默认使用当前时区分钟偏移量\n * @returns 时区序号\n */\n static getUTCOffset(timezoneOffset = TimezoneDate.getTimezoneOffset()) {\n return timezoneOffset / -60;\n }\n}\n","import { objectEach } from '@/object';\nimport { isDate, isString } from '@/type';\nimport { TimezoneDate } from './timezone';\n\n/**\n * 判断一个值是否为有效的日期对象\n * @param unknown - 需要判断的值\n * @returns 如果值是有效的日期对象则返回 true,否则返回 false\n * @example\n * ```typescript\n * isValidDate(new Date()); // true\n * isValidDate('2023-01-01'); // false\n * isValidDate(NaN); // false\n * ```\n */\nexport function isValidDate(unknown: unknown): unknown is Date | TimezoneDate {\n return (\n (unknown instanceof Date && !Number.isNaN(unknown.getTime())) ||\n (unknown instanceof TimezoneDate && !Number.isNaN(unknown.getTime()))\n );\n}\n\nexport type DateLike = Date | TimezoneDate;\nexport type DateValue = number | string | DateLike;\n\nfunction _guessDateSeparator(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const value2 = value.replace(/-/g, '/');\n\n return new Date(value2);\n}\n\nfunction _guessDateTimezone(value: DateValue): Date | undefined {\n if (!isString(value)) return;\n\n const re = /([+-])(\\d\\d)(\\d\\d)$/;\n\n const matches = re.exec(value);\n\n if (!matches) return;\n\n const value2 = value.replace(re, 'Z');\n const d = new Date(value2);\n\n if (!isValidDate(d)) return;\n\n const [, flag, hours, minutes] = matches;\n const hours2 = Number.parseInt(hours, 10);\n const minutes2 = Number.parseInt(minutes, 10);\n const offset = (a: number, b: number): number => (flag === '+' ? a - b : a + b);\n\n d.setHours(offset(d.getHours(), hours2));\n d.setMinutes(offset(d.getMinutes(), minutes2));\n\n return d;\n}\n\n/**\n * 解析为Date对象\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @returns 解析后的 Date 对象\n * @throws {SyntaxError} 如果无法解析为有效的日期对象,则抛出错误\n * @example\n * ```typescript\n * dateParse('2023-01-01'); // Date对象\n * dateParse(1672531200000); // Date对象\n * dateParse(new Date()); // Date对象\n * dateParse('invalid date'); // 抛出 SyntaxError\n * ```\n */\nexport function dateParse(dateValue: DateValue): DateLike {\n // 传入的 Date 对象有 Date、TimezoneDate\n // @ts-ignore\n const d1 = isDate(dateValue)\n ? new Date(dateValue)\n : dateValue instanceof TimezoneDate\n ? new TimezoneDate(dateValue)\n : new Date(dateValue);\n if (isValidDate(d1)) return d1;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26 18:06:15') 返回值是一个非法日期对象\n const d2 = _guessDateSeparator(dateValue);\n if (isValidDate(d2)) return d2;\n\n // safari 浏览器的日期解析有问题\n // new Date('2020-06-26T18:06:15.000+0800') 返回值是一个非法日期对象\n const d3 = _guessDateTimezone(dateValue);\n if (isValidDate(d3)) return d3;\n\n throw new SyntaxError(`${dateValue.toString()} 不是一个合法的日期值`);\n}\n\nfunction _pad(num: number, len = 2) {\n return `${num}`.padStart(len, '0');\n}\n\nconst rules: [RegExp, (date: DateLike) => number | string][] = [\n [/Y{4}/gi, (date) => date.getFullYear()],\n [/Y{2}/gi, (date) => date.getFullYear() % 100],\n [/M{2}/g, (date) => _pad(date.getMonth() + 1)],\n [/M{1}/g, (date) => date.getMonth() + 1],\n [/D{2}/gi, (date) => _pad(date.getDate())],\n [/D{1}/gi, (date) => date.getDate()],\n [/H{2}/g, (date) => _pad(date.getHours())],\n [/H{1}/g, (date) => date.getHours()],\n [\n /h{2}/g,\n (date) => {\n const h = date.getHours();\n return _pad(h > 12 ? h - 12 : h);\n },\n ],\n [\n /h{1}/g,\n (date) => {\n const h = date.getHours();\n return h > 12 ? h - 12 : h;\n },\n ],\n [/m{2}/g, (date) => _pad(date.getMinutes())],\n [/m{1}/g, (date) => date.getMinutes()],\n [/s{2}/g, (date) => _pad(date.getSeconds())],\n [/s{1}/g, (date) => date.getSeconds()],\n [/S{3}/g, (date) => _pad(date.getMilliseconds(), 3)],\n [/S{2}/g, (date) => _pad(date.getMilliseconds(), 2)],\n [/S{1}/g, (date) => date.getMilliseconds()],\n];\n\n/**\n * 格式化为日期字符串(带自定义格式化模板)\n * @param dateValue - 可以是数值、字符串或 Date 对象\n * @param format - 模板,默认是 'YYYY-MM-DD HH:mm:ss',模板字符:\n * - YYYY:年\n * - yyyy: 年\n * - MM:月\n * - DD:日\n * - dd: 日\n * - HH:时(24 小时制)\n * - hh:时(12 小时制)\n * - mm:分\n * - ss:秒\n * - SSS:毫秒\n * @returns 格式化后的日期字符串\n * @example\n * ```typescript\n * dateFormat(new Date(), 'YYYY-MM-DD'); // '2023-01-01'\n * dateFormat(1672531200000, 'YYYY/MM/DD HH:mm:ss'); // '2023/01/01 00:00:00'\n * dateFormat('2023-01-01', 'YYYY年MM月DD日'); // '2023年01月01日'\n * ```\n */\nexport function dateFormat(dateValue: DateValue, format = 'YYYY-MM-DD HH:mm:ss'): string {\n const date = dateParse(dateValue);\n let result = format;\n\n for (const rule of rules) {\n result = result.replace(rule[0], String(rule[1](date)));\n }\n\n return result;\n}\n"],"names":["timestamp"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { TzDate } from './timezone';
1
+ import { TimezoneDate } from './timezone';
2
2
  /**
3
3
  * 判断一个值是否为有效的日期对象
4
4
  * @param unknown - 需要判断的值
@@ -10,8 +10,8 @@ import { TzDate } from './timezone';
10
10
  * isValidDate(NaN); // false
11
11
  * ```
12
12
  */
13
- export declare function isValidDate(unknown: unknown): unknown is Date | TzDate;
14
- export type DateLike = Date | TzDate;
13
+ export declare function isValidDate(unknown: unknown): unknown is Date | TimezoneDate;
14
+ export type DateLike = Date | TimezoneDate;
15
15
  export type DateValue = number | string | DateLike;
16
16
  /**
17
17
  * 解析为Date对象
@@ -1,4 +1,4 @@
1
- export type TzDateOptions = {
1
+ export type TimezoneDateOptions = {
2
2
  /**
3
3
  * 时间戳
4
4
  * @default Date.now()
@@ -17,30 +17,34 @@ export type TzDateOptions = {
17
17
  milliseconds?: number
18
18
  ];
19
19
  /**
20
- * 时区偏移量,单位为分钟,默认为当前时区
20
+ * UTC 时区,支持负数和小数,例如:
21
+ * - 8 表示 UTC+8
22
+ * - -12 表示 UTC-12
23
+ * - 0 表示 UTC 时间
24
+ * - 12.5 表示 UTC+12:30
21
25
  */
22
- offset?: number;
26
+ utcOffset?: number;
23
27
  };
24
28
  /**
25
29
  * 时区日期类,用于处理不同时区的日期时间
26
30
  */
27
- export declare class TzDate {
31
+ export declare class TimezoneDate {
28
32
  #private;
29
33
  /**
30
- * 构造一个 TzDate 实例
34
+ * 构造一个 TimezoneDate 实例
31
35
  * @param options - 配置选项
32
36
  */
33
- constructor(options?: TzDateOptions | TzDate);
37
+ constructor(options?: TimezoneDateOptions | TimezoneDate);
34
38
  /**
35
39
  * 获取时区偏移量(分钟)
36
40
  * @returns 时区偏移量
37
41
  */
38
42
  getTimezoneOffset(): number;
39
43
  /**
40
- * 获取时区序号
44
+ * 获取时区偏移量(UTC)
41
45
  * @returns 时区序号
42
46
  */
43
- getTimezoneOrder(): number;
47
+ getUTCOffset(): number;
44
48
  /**
45
49
  * 获取年份
46
50
  * @returns 年份
@@ -143,26 +147,30 @@ export declare class TzDate {
143
147
  */
144
148
  toISOString(): string;
145
149
  /**
146
- * 创建一个 TzDate 对象
150
+ * 转换为指定时区的 TimezoneDate 对象
147
151
  * @param td - 需要转换的日期对象
148
152
  * @param offset - 目标时区分钟偏移量,默认为当前时区
149
- * @returns 返回一个 TzDate 对象
153
+ * @returns 返回一个 TimezoneDate 对象
150
154
  * @example
151
155
  * ```js
152
- * const tzDate = TzDate.from(new TzDate());
156
+ * // 转换为 UTC 时间
157
+ * const utc0Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 0);
158
+ *
159
+ * // 转换为东八区时间
160
+ * const utc8Td = TimezoneDate.changeUtcOffset(new TimezoneDate(), 8);
153
161
  * ```
154
162
  */
155
- static from(td: TzDate, offset?: number): TzDate;
156
- /**
157
- * 获取时区序号
158
- * @param offset - 默认使用当前时区分钟偏移量
159
- * @returns 时区序号
160
- */
161
- static getOrder(offset?: number): number;
163
+ static changeUtcOffset(td: TimezoneDate, utcOffset: number): TimezoneDate;
162
164
  /**
163
165
  * 获取时区分钟偏移量
164
- * @param gmtOrder - 默认使用当前时区序号
166
+ * @param utcOffset - 默认使用当前时区
165
167
  * @returns 时区分钟偏移量
166
168
  */
167
- static getOffset(gmtOrder?: number): number;
169
+ static getTimezoneOffset(utcOffset?: number): number;
170
+ /**
171
+ * 获取时区序号
172
+ * @param timezoneOffset - 默认使用当前时区分钟偏移量
173
+ * @returns 时区序号
174
+ */
175
+ static getUTCOffset(timezoneOffset?: number): number;
168
176
  }
package/dist/date.cjs CHANGED
@@ -206,7 +206,7 @@ exports.DATE_MINUTE_MS = _const.DATE_MINUTE_MS;
206
206
  exports.DATE_MONTH_MS = _const.DATE_MONTH_MS;
207
207
  exports.DATE_SECOND_MS = _const.DATE_SECOND_MS;
208
208
  exports.DATE_YEAR_MS = _const.DATE_YEAR_MS;
209
- exports.TzDate = core.TzDate;
209
+ exports.TimezoneDate = core.TimezoneDate;
210
210
  exports.dateFormat = core.dateFormat;
211
211
  exports.dateParse = core.dateParse;
212
212
  exports.isValidDate = core.isValidDate;
package/dist/date.mjs CHANGED
@@ -208,7 +208,7 @@ export {
208
208
  e as DATE_SECOND_MS,
209
209
  D as DATE_YEAR_MS,
210
210
  EWeekStart,
211
- T as TzDate,
211
+ T as TimezoneDate,
212
212
  _dateWeeks,
213
213
  dateDaysInMonth,
214
214
  dateDaysInYear,
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const VERSION = "1.15.7";
3
+ const VERSION = "1.16.0";
4
4
  exports.VERSION = VERSION;
5
5
  //# sourceMappingURL=index.cjs.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = "1.15.7";
1
+ const VERSION = "1.16.0";
2
2
  export {
3
3
  VERSION
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudcome/utils-core",
3
- "version": "1.16.0",
3
+ "version": "1.17.0",
4
4
  "description": "cloudcome core utils",
5
5
  "engines": {
6
6
  "node": ">=22"