@simplysm/core-common 13.0.100 → 14.0.4
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 +86 -92
- package/dist/common.types.d.ts +14 -14
- package/dist/common.types.js +2 -1
- package/dist/common.types.js.map +1 -6
- package/dist/env.d.ts +8 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +13 -9
- package/dist/env.js.map +1 -6
- package/dist/errors/argument-error.d.ts +10 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +31 -14
- package/dist/errors/argument-error.js.map +1 -6
- package/dist/errors/not-implemented-error.d.ts +8 -8
- package/dist/errors/not-implemented-error.js +30 -12
- package/dist/errors/not-implemented-error.js.map +1 -6
- package/dist/errors/sd-error.d.ts +10 -10
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/sd-error.js +45 -24
- package/dist/errors/sd-error.js.map +1 -6
- package/dist/errors/timeout-error.d.ts +10 -10
- package/dist/errors/timeout-error.js +34 -15
- package/dist/errors/timeout-error.js.map +1 -6
- package/dist/extensions/arr-ext.d.ts +2 -2
- package/dist/extensions/arr-ext.helpers.d.ts +10 -10
- package/dist/extensions/arr-ext.helpers.js +112 -89
- package/dist/extensions/arr-ext.helpers.js.map +1 -6
- package/dist/extensions/arr-ext.js +458 -422
- package/dist/extensions/arr-ext.js.map +1 -6
- package/dist/extensions/arr-ext.types.d.ts +57 -57
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/arr-ext.types.js +6 -1
- package/dist/extensions/arr-ext.types.js.map +1 -6
- package/dist/extensions/map-ext.d.ts +16 -16
- package/dist/extensions/map-ext.js +27 -22
- package/dist/extensions/map-ext.js.map +1 -6
- package/dist/extensions/set-ext.d.ts +11 -11
- package/dist/extensions/set-ext.js +32 -25
- package/dist/extensions/set-ext.js.map +1 -6
- package/dist/features/debounce-queue.d.ts +17 -17
- package/dist/features/debounce-queue.js +98 -70
- package/dist/features/debounce-queue.js.map +1 -6
- package/dist/features/event-emitter.d.ts +20 -20
- package/dist/features/event-emitter.js +101 -78
- package/dist/features/event-emitter.js.map +1 -6
- package/dist/features/serial-queue.d.ts +11 -11
- package/dist/features/serial-queue.js +78 -57
- package/dist/features/serial-queue.js.map +1 -6
- package/dist/globals.d.ts +4 -4
- package/dist/globals.js +9 -1
- package/dist/globals.js.map +1 -6
- package/dist/index.js +28 -27
- package/dist/index.js.map +1 -6
- package/dist/types/date-only.d.ts +64 -64
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +263 -252
- package/dist/types/date-only.js.map +1 -6
- package/dist/types/date-time.d.ts +36 -36
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +196 -288
- package/dist/types/date-time.js.map +1 -6
- package/dist/types/lazy-gc-map.d.ts +26 -26
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +202 -159
- package/dist/types/lazy-gc-map.js.map +1 -6
- package/dist/types/time.d.ts +23 -23
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +169 -158
- package/dist/types/time.js.map +1 -6
- package/dist/types/uuid.d.ts +11 -11
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +95 -70
- package/dist/types/uuid.js.map +1 -6
- package/dist/utils/bytes.d.ts +17 -17
- package/dist/utils/bytes.js +137 -81
- package/dist/utils/bytes.js.map +1 -6
- package/dist/utils/date-format.d.ts +40 -40
- package/dist/utils/date-format.js +187 -101
- package/dist/utils/date-format.js.map +1 -6
- package/dist/utils/error.d.ts +4 -4
- package/dist/utils/error.js +11 -6
- package/dist/utils/error.js.map +1 -6
- package/dist/utils/json.d.ts +19 -19
- package/dist/utils/json.js +187 -135
- package/dist/utils/json.js.map +1 -6
- package/dist/utils/num.d.ts +20 -20
- package/dist/utils/num.js +76 -34
- package/dist/utils/num.js.map +1 -6
- package/dist/utils/obj.d.ts +111 -111
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +706 -496
- package/dist/utils/obj.js.map +1 -6
- package/dist/utils/path.d.ts +10 -10
- package/dist/utils/path.js +35 -18
- package/dist/utils/path.js.map +1 -6
- package/dist/utils/primitive.d.ts +5 -5
- package/dist/utils/primitive.js +34 -14
- package/dist/utils/primitive.js.map +1 -6
- package/dist/utils/str.d.ts +38 -38
- package/dist/utils/str.js +217 -113
- package/dist/utils/str.js.map +1 -6
- package/dist/utils/template-strings.d.ts +26 -26
- package/dist/utils/template-strings.js +113 -40
- package/dist/utils/template-strings.js.map +1 -6
- package/dist/utils/transferable.d.ts +18 -18
- package/dist/utils/transferable.js +218 -151
- package/dist/utils/transferable.js.map +1 -6
- package/dist/utils/wait.d.ts +9 -9
- package/dist/utils/wait.js +30 -15
- package/dist/utils/wait.js.map +1 -6
- package/dist/utils/xml.d.ts +13 -13
- package/dist/utils/xml.js +84 -46
- package/dist/utils/xml.js.map +1 -6
- package/dist/utils/zip.d.ts +22 -22
- package/dist/utils/zip.js +172 -148
- package/dist/utils/zip.js.map +1 -6
- package/docs/array-extensions.md +430 -0
- package/docs/env.md +52 -0
- package/docs/errors.md +41 -56
- package/docs/features.md +82 -97
- package/docs/type-utilities.md +91 -0
- package/docs/types.md +221 -201
- package/docs/utils.md +319 -435
- package/package.json +7 -5
- package/src/common.types.ts +14 -14
- package/src/env.ts +12 -3
- package/src/errors/argument-error.ts +15 -15
- package/src/errors/not-implemented-error.ts +9 -9
- package/src/errors/sd-error.ts +12 -12
- package/src/errors/timeout-error.ts +12 -12
- package/src/extensions/arr-ext.helpers.ts +16 -16
- package/src/extensions/arr-ext.ts +35 -35
- package/src/extensions/arr-ext.types.ts +57 -57
- package/src/extensions/map-ext.ts +16 -16
- package/src/extensions/set-ext.ts +11 -11
- package/src/features/debounce-queue.ts +23 -23
- package/src/features/event-emitter.ts +25 -25
- package/src/features/serial-queue.ts +13 -13
- package/src/globals.ts +4 -4
- package/src/index.ts +5 -5
- package/src/types/date-only.ts +84 -83
- package/src/types/date-time.ts +43 -42
- package/src/types/lazy-gc-map.ts +44 -44
- package/src/types/time.ts +29 -29
- package/src/types/uuid.ts +15 -15
- package/src/utils/bytes.ts +35 -35
- package/src/utils/date-format.ts +59 -59
- package/src/utils/error.ts +4 -4
- package/src/utils/json.ts +41 -41
- package/src/utils/num.ts +20 -20
- package/src/utils/obj.ts +138 -138
- package/src/utils/path.ts +10 -10
- package/src/utils/primitive.ts +6 -6
- package/src/utils/str.ts +48 -48
- package/src/utils/template-strings.ts +29 -29
- package/src/utils/transferable.ts +38 -38
- package/src/utils/wait.ts +10 -10
- package/src/utils/xml.ts +19 -19
- package/src/utils/zip.ts +25 -25
- package/docs/extensions.md +0 -387
- package/tests/errors/errors.spec.ts +0 -80
- package/tests/extensions/array-extension.spec.ts +0 -654
- package/tests/extensions/map-extension.spec.ts +0 -117
- package/tests/extensions/set-extension.spec.ts +0 -67
- package/tests/types/date-only.spec.ts +0 -533
- package/tests/types/date-time.spec.ts +0 -246
- package/tests/types/lazy-gc-map.spec.ts +0 -606
- package/tests/types/time.spec.ts +0 -428
- package/tests/types/uuid.spec.ts +0 -74
- package/tests/utils/bytes-utils.spec.ts +0 -197
- package/tests/utils/date-format.spec.ts +0 -350
- package/tests/utils/debounce-queue.spec.ts +0 -226
- package/tests/utils/json.spec.ts +0 -400
- package/tests/utils/number.spec.ts +0 -136
- package/tests/utils/object.spec.ts +0 -810
- package/tests/utils/path.spec.ts +0 -70
- package/tests/utils/primitive.spec.ts +0 -43
- package/tests/utils/sd-event-emitter.spec.ts +0 -189
- package/tests/utils/serial-queue.spec.ts +0 -305
- package/tests/utils/string.spec.ts +0 -265
- package/tests/utils/template-strings.spec.ts +0 -48
- package/tests/utils/transferable.spec.ts +0 -639
- package/tests/utils/wait.spec.ts +0 -123
- package/tests/utils/xml.spec.ts +0 -146
- package/tests/utils/zip.spec.ts +0 -221
package/src/types/date-only.ts
CHANGED
|
@@ -2,10 +2,10 @@ import { ArgumentError } from "../errors/argument-error";
|
|
|
2
2
|
import { format, normalizeMonth } from "../utils/date-format";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* 날짜 클래스 (시간 제외: yyyy-MM-dd, 불변)
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* 시간 정보 없이 날짜만 저장하는 불변 클래스.
|
|
8
|
+
* 로컬 타임존 기준으로 동작함.
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* const today = new DateOnly();
|
|
@@ -17,13 +17,13 @@ export class DateOnly {
|
|
|
17
17
|
|
|
18
18
|
readonly date: Date;
|
|
19
19
|
|
|
20
|
-
/**
|
|
20
|
+
/** 현재 시간 */
|
|
21
21
|
constructor();
|
|
22
|
-
/**
|
|
22
|
+
/** 년, 월, 일로 초기화 */
|
|
23
23
|
constructor(year: number, month: number, day: number);
|
|
24
|
-
/**
|
|
24
|
+
/** tick (밀리초)으로 생성 */
|
|
25
25
|
constructor(tick: number);
|
|
26
|
-
/**
|
|
26
|
+
/** Date 타입으로 생성 */
|
|
27
27
|
constructor(date: Date);
|
|
28
28
|
constructor(arg1?: number | Date, arg2?: number, arg3?: number) {
|
|
29
29
|
if (arg1 === undefined) {
|
|
@@ -42,26 +42,26 @@ export class DateOnly {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
46
|
-
* @param str
|
|
47
|
-
* @returns DateOnly
|
|
45
|
+
* 문자열을 DateOnly로 파싱
|
|
46
|
+
* @param str 날짜 문자열
|
|
47
|
+
* @returns DateOnly 인스턴스
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
* - `yyyy-MM-dd` (
|
|
51
|
-
* - `yyyyMMdd` (
|
|
52
|
-
* - ISO 8601 (
|
|
49
|
+
* 지원 형식:
|
|
50
|
+
* - `yyyy-MM-dd` (예: '2024-01-15') - 문자열에서 직접 추출, 타임존 무관
|
|
51
|
+
* - `yyyyMMdd` (예: '20240115') - 문자열에서 직접 추출, 타임존 무관
|
|
52
|
+
* - ISO 8601 (예: '2024-01-15T00:00:00Z') - UTC로 해석 후 로컬 타임존으로 변환
|
|
53
53
|
*
|
|
54
|
-
* @note
|
|
55
|
-
* @note
|
|
54
|
+
* @note 서버/클라이언트 타임존이 다른 경우 `yyyy-MM-dd` 형식 권장
|
|
55
|
+
* @note DST 지역에서 ISO 8601 형식 파싱 시 파싱 대상 날짜의 오프셋이 사용됨.
|
|
56
56
|
*/
|
|
57
57
|
static parse(str: string): DateOnly {
|
|
58
|
-
// yyyy-MM-dd
|
|
58
|
+
// yyyy-MM-dd 형식 (타임존 무관)
|
|
59
59
|
const matchYMD = /^(\d{4})-(\d{2})-(\d{2})$/.exec(str);
|
|
60
60
|
if (matchYMD != null) {
|
|
61
61
|
return new DateOnly(Number(matchYMD[1]), Number(matchYMD[2]), Number(matchYMD[3]));
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// yyyyMMdd
|
|
64
|
+
// yyyyMMdd 형식 (타임존 무관)
|
|
65
65
|
const matchCompact = /^(\d{4})(\d{2})(\d{2})$/.exec(str);
|
|
66
66
|
if (matchCompact != null) {
|
|
67
67
|
return new DateOnly(
|
|
@@ -71,11 +71,11 @@ export class DateOnly {
|
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
// ISO 8601
|
|
75
|
-
// Date.parse()
|
|
76
|
-
// getTimezoneOffset()
|
|
77
|
-
//
|
|
78
|
-
//
|
|
74
|
+
// ISO 8601 및 기타 형식 (Date.parse 사용, 타임존 변환 적용)
|
|
75
|
+
// Date.parse()는 'Z' 접미사가 있는 ISO 8601에 대해 UTC tick을 반환
|
|
76
|
+
// getTimezoneOffset()은 "로컬에서 UTC로 변환할 때 더해야 하는 분"을 반환 (KST는 -540 = UTC+9)
|
|
77
|
+
// 여기서는 "UTC → 로컬" 변환이므로 반대 부호 적용 (빼기)
|
|
78
|
+
// DST 지역에서 정확한 변환을 위해 파싱 대상 날짜의 오프셋 사용
|
|
79
79
|
const utcTick = Date.parse(str);
|
|
80
80
|
if (!Number.isNaN(utcTick)) {
|
|
81
81
|
const tempDate = new Date(utcTick);
|
|
@@ -85,45 +85,45 @@ export class DateOnly {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
throw new ArgumentError(
|
|
88
|
-
|
|
88
|
+
`날짜 형식 파싱 실패. 지원 형식: 'yyyy-MM-dd', 'yyyyMMdd', ISO 8601 date`,
|
|
89
89
|
{
|
|
90
90
|
input: str,
|
|
91
91
|
},
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
//#region
|
|
95
|
+
//#region 주차 계산
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
99
|
-
* @param weekStartDay
|
|
100
|
-
* @param minDaysInFirstWeek
|
|
101
|
-
* @returns
|
|
98
|
+
* 주차 정보 기반으로 기준 연도와 월 반환
|
|
99
|
+
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
100
|
+
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
101
|
+
* @returns 이 날짜가 포함된 주의 기준 연도와 월
|
|
102
102
|
*
|
|
103
103
|
* @example
|
|
104
|
-
* // ISO 8601
|
|
104
|
+
* // ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)
|
|
105
105
|
* new DateOnly(2024, 1, 1).getBaseYearMonthSeqForWeekSeq(1, 4)
|
|
106
|
-
* //
|
|
106
|
+
* // 미국식 (일요일 시작, 첫 주 최소 1일)
|
|
107
107
|
* new DateOnly(2024, 1, 1).getBaseYearMonthSeqForWeekSeq(0, 1)
|
|
108
108
|
*/
|
|
109
109
|
getBaseYearMonthSeqForWeekSeq(weekStartDay: number = 1, minDaysInFirstWeek: number = 4) {
|
|
110
|
-
//
|
|
110
|
+
// 주 시작 요일 기준 요일 인덱스 계산 (0 = 주 시작 요일)
|
|
111
111
|
const dayOfWeek = (this.dayOfWeek + 7 - weekStartDay) % 7;
|
|
112
|
-
//
|
|
112
|
+
// 현재 주의 남은 일수 (현재 날짜 포함)
|
|
113
113
|
const daysInWeek = 7 - dayOfWeek;
|
|
114
114
|
|
|
115
|
-
//
|
|
115
|
+
// 현재 주의 남은 일수가 최소 일수보다 적으면 이전 주로 간주
|
|
116
116
|
if (daysInWeek < minDaysInFirstWeek) {
|
|
117
117
|
const prevWeek = this.addDays(-7);
|
|
118
118
|
return { year: prevWeek.year, monthSeq: prevWeek.month };
|
|
119
119
|
} else {
|
|
120
|
-
//
|
|
120
|
+
// 월 경계를 고려한 실제 남은 일수 계산
|
|
121
121
|
const nextMonthDate = this.addMonths(1).setDay(1);
|
|
122
122
|
const remainedDays = (nextMonthDate.tick - this.tick) / DateOnly.MS_PER_DAY;
|
|
123
123
|
|
|
124
|
-
//
|
|
124
|
+
// 월 경계까지의 실제 일수와 주 남은 일수 중 작은 값 사용
|
|
125
125
|
const realDaysInWeek = Math.min(daysInWeek, remainedDays);
|
|
126
|
-
//
|
|
126
|
+
// 월 경계를 고려했을 때도 최소 일수보다 적으면 다음 주로 간주
|
|
127
127
|
if (realDaysInWeek < minDaysInFirstWeek) {
|
|
128
128
|
const nextWeek = this.addDays(7);
|
|
129
129
|
return { year: nextWeek.year, monthSeq: nextWeek.month };
|
|
@@ -134,10 +134,10 @@ export class DateOnly {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
|
-
*
|
|
138
|
-
* @param weekStartDay
|
|
139
|
-
* @param minDaysInFirstWeek
|
|
140
|
-
* @returns
|
|
137
|
+
* 주차 정보 기반으로 해당 주의 시작 날짜 계산
|
|
138
|
+
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
139
|
+
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
140
|
+
* @returns 이 날짜가 포함된 주의 시작 날짜
|
|
141
141
|
*/
|
|
142
142
|
getWeekSeqStartDate(weekStartDay: number = 1, minDaysInFirstWeek: number = 4) {
|
|
143
143
|
const dayOfWeek = (this.dayOfWeek + 7 - weekStartDay) % 7;
|
|
@@ -151,16 +151,16 @@ export class DateOnly {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/**
|
|
154
|
-
*
|
|
155
|
-
* @param weekStartDay
|
|
156
|
-
* @param minDaysInFirstWeek
|
|
157
|
-
* @returns
|
|
154
|
+
* 연도와 주차 정보 반환
|
|
155
|
+
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
156
|
+
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
157
|
+
* @returns 해당 연도와 그 연도 내의 주차 번호
|
|
158
158
|
*
|
|
159
159
|
* @example
|
|
160
|
-
* // ISO 8601
|
|
160
|
+
* // ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)
|
|
161
161
|
* new DateOnly(2025, 1, 6).getWeekSeqOfYear(); // { year: 2025, weekSeq: 2 }
|
|
162
162
|
*
|
|
163
|
-
* //
|
|
163
|
+
* // 미국식 (일요일 시작, 첫 주 최소 1일)
|
|
164
164
|
* new DateOnly(2025, 1, 1).getWeekSeqOfYear(0, 1); // { year: 2025, weekSeq: 1 }
|
|
165
165
|
*/
|
|
166
166
|
getWeekSeqOfYear(
|
|
@@ -182,16 +182,16 @@ export class DateOnly {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/**
|
|
185
|
-
*
|
|
186
|
-
* @param weekStartDay
|
|
187
|
-
* @param minDaysInFirstWeek
|
|
188
|
-
* @returns
|
|
185
|
+
* 해당 날짜의 연도, 월, 주차 정보 반환
|
|
186
|
+
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
187
|
+
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
188
|
+
* @returns 연도, 월, 해당 월 내의 주차 번호
|
|
189
189
|
*
|
|
190
190
|
* @example
|
|
191
|
-
* // ISO 8601
|
|
191
|
+
* // ISO 8601 표준 (월요일 시작, 첫 주 최소 4일)
|
|
192
192
|
* new DateOnly(2025, 1, 15).getWeekSeqOfMonth(); // { year: 2025, monthSeq: 1, weekSeq: 3 }
|
|
193
193
|
*
|
|
194
|
-
* //
|
|
194
|
+
* // 미국식 (일요일 시작, 첫 주 최소 1일)
|
|
195
195
|
* new DateOnly(2025, 1, 15).getWeekSeqOfMonth(0, 1); // { year: 2025, monthSeq: 1, weekSeq: 3 }
|
|
196
196
|
*/
|
|
197
197
|
getWeekSeqOfMonth(
|
|
@@ -214,18 +214,18 @@ export class DateOnly {
|
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
/**
|
|
217
|
-
*
|
|
218
|
-
* @param arg
|
|
219
|
-
* @param weekStartDay
|
|
220
|
-
* @param minDaysInFirstWeek
|
|
221
|
-
* @returns
|
|
217
|
+
* 주차 정보 기반으로 해당 주의 시작 날짜 반환
|
|
218
|
+
* @param arg 연도, 선택적 월, 주차 번호
|
|
219
|
+
* @param weekStartDay 주 시작 요일 (0=일요일, 1=월요일, ..., 6=토요일). 기본값: 1(월요일)
|
|
220
|
+
* @param minDaysInFirstWeek 첫 번째 주로 간주되기 위한 최소 일수 (1~7). 기본값: 4 (ISO 8601 표준)
|
|
221
|
+
* @returns 지정된 주의 시작 날짜
|
|
222
222
|
*
|
|
223
223
|
* @example
|
|
224
|
-
* //
|
|
225
|
-
* DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 2 }); // 2025-01-06 (
|
|
224
|
+
* // 2025년 2주차 시작 날짜 (ISO 8601 표준)
|
|
225
|
+
* DateOnly.getDateByYearWeekSeq({ year: 2025, weekSeq: 2 }); // 2025-01-06 (월요일)
|
|
226
226
|
*
|
|
227
|
-
* //
|
|
228
|
-
* DateOnly.getDateByYearWeekSeq({ year: 2025, month: 1, weekSeq: 3 }); // 2025-01-13 (
|
|
227
|
+
* // 2025년 1월 3주차 시작 날짜
|
|
228
|
+
* DateOnly.getDateByYearWeekSeq({ year: 2025, month: 1, weekSeq: 3 }); // 2025-01-13 (월요일)
|
|
229
229
|
*/
|
|
230
230
|
static getDateByYearWeekSeq(
|
|
231
231
|
arg: { year: number; month?: number; weekSeq: number },
|
|
@@ -240,9 +240,9 @@ export class DateOnly {
|
|
|
240
240
|
|
|
241
241
|
//#endregion
|
|
242
242
|
|
|
243
|
-
//#region Getters (
|
|
243
|
+
//#region Getters (읽기 전용)
|
|
244
244
|
|
|
245
|
-
/**
|
|
245
|
+
/** 날짜가 올바르게 설정되었는지 여부 */
|
|
246
246
|
get isValid(): boolean {
|
|
247
247
|
return this.date instanceof Date && !Number.isNaN(this.date.getTime());
|
|
248
248
|
}
|
|
@@ -263,25 +263,26 @@ export class DateOnly {
|
|
|
263
263
|
return this.date.getTime();
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
/**
|
|
266
|
+
/** 요일 (일요일~토요일: 0~6) */
|
|
267
267
|
get dayOfWeek(): number {
|
|
268
268
|
return this.date.getDay();
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
//#endregion
|
|
272
272
|
|
|
273
|
-
//#region
|
|
273
|
+
//#region 불변 변환 메서드 (새 인스턴스 반환)
|
|
274
274
|
|
|
275
|
-
/**
|
|
275
|
+
/** 지정된 연도로 새 인스턴스 반환 */
|
|
276
276
|
setYear(year: number): DateOnly {
|
|
277
|
-
|
|
277
|
+
const lastDay = new Date(year, this.month, 0).getDate();
|
|
278
|
+
return new DateOnly(year, this.month, Math.min(this.day, lastDay));
|
|
278
279
|
}
|
|
279
280
|
|
|
280
281
|
/**
|
|
281
|
-
*
|
|
282
|
-
* @param month
|
|
283
|
-
* @note
|
|
284
|
-
* (
|
|
282
|
+
* 지정된 월로 새 DateOnly 인스턴스 반환
|
|
283
|
+
* @param month 설정할 월 (1-12, 범위 밖의 값은 연도에서 조정됨)
|
|
284
|
+
* @note 현재 일이 대상 월의 일수보다 크면 해당 월의 마지막 일로 조정됨
|
|
285
|
+
* (예: 1월 31일에서 setMonth(2) → 2월 28일 또는 29일)
|
|
285
286
|
*/
|
|
286
287
|
setMonth(month: number): DateOnly {
|
|
287
288
|
const normalized = normalizeMonth(this.year, month, this.day);
|
|
@@ -289,10 +290,10 @@ export class DateOnly {
|
|
|
289
290
|
}
|
|
290
291
|
|
|
291
292
|
/**
|
|
292
|
-
*
|
|
293
|
-
* @param day
|
|
294
|
-
* @note
|
|
295
|
-
* (
|
|
293
|
+
* 지정된 일로 새 DateOnly 인스턴스 반환
|
|
294
|
+
* @param day 설정할 일
|
|
295
|
+
* @note 유효한 월 범위를 벗어나는 일은 JavaScript Date 동작에 따라 자동으로 다음/이전 월로 조정됨
|
|
296
|
+
* (예: 1월에 day=32 → 2월 1일)
|
|
296
297
|
*/
|
|
297
298
|
setDay(day: number): DateOnly {
|
|
298
299
|
return new DateOnly(this.year, this.month, day);
|
|
@@ -300,19 +301,19 @@ export class DateOnly {
|
|
|
300
301
|
|
|
301
302
|
//#endregion
|
|
302
303
|
|
|
303
|
-
//#region
|
|
304
|
+
//#region 산술 메서드 (새 인스턴스 반환)
|
|
304
305
|
|
|
305
|
-
/**
|
|
306
|
+
/** 지정된 연수를 더한 새 인스턴스 반환 */
|
|
306
307
|
addYears(years: number): DateOnly {
|
|
307
308
|
return this.setYear(this.year + years);
|
|
308
309
|
}
|
|
309
310
|
|
|
310
|
-
/**
|
|
311
|
+
/** 지정된 월수를 더한 새 인스턴스 반환 */
|
|
311
312
|
addMonths(months: number): DateOnly {
|
|
312
313
|
return this.setMonth(this.month + months);
|
|
313
314
|
}
|
|
314
315
|
|
|
315
|
-
/**
|
|
316
|
+
/** 지정된 일수를 더한 새 인스턴스 반환 */
|
|
316
317
|
addDays(days: number): DateOnly {
|
|
317
318
|
return new DateOnly(this.tick + days * DateOnly.MS_PER_DAY);
|
|
318
319
|
}
|
|
@@ -322,9 +323,9 @@ export class DateOnly {
|
|
|
322
323
|
//#region Formatting
|
|
323
324
|
|
|
324
325
|
/**
|
|
325
|
-
*
|
|
326
|
-
* @param format
|
|
327
|
-
* @see dtFormat
|
|
326
|
+
* 지정된 형식으로 문자열 변환
|
|
327
|
+
* @param format 형식 문자열
|
|
328
|
+
* @see dtFormat 지원되는 형식 문자열 참조
|
|
328
329
|
*/
|
|
329
330
|
toFormatString(formatStr: string): string {
|
|
330
331
|
return format(formatStr, {
|
package/src/types/date-time.ts
CHANGED
|
@@ -2,10 +2,10 @@ import { ArgumentError } from "../errors/argument-error";
|
|
|
2
2
|
import { convert12To24, format, normalizeMonth } from "../utils/date-format";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* DateTime
|
|
5
|
+
* DateTime 클래스 (불변)
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* JavaScript Date 객체를 래핑하여 불변성과 편리한 API를 제공.
|
|
8
|
+
* 밀리초 정밀도를 지원하고 로컬 타임존 기준으로 동작함.
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* const now = new DateTime();
|
|
@@ -15,9 +15,9 @@ import { convert12To24, format, normalizeMonth } from "../utils/date-format";
|
|
|
15
15
|
export class DateTime {
|
|
16
16
|
readonly date: Date;
|
|
17
17
|
|
|
18
|
-
/**
|
|
18
|
+
/** 현재 시간으로 생성 */
|
|
19
19
|
constructor();
|
|
20
|
-
/**
|
|
20
|
+
/** 년, 월, 일, 시, 분, 초, 밀리초로 생성 */
|
|
21
21
|
constructor(
|
|
22
22
|
year: number,
|
|
23
23
|
month: number,
|
|
@@ -27,9 +27,9 @@ export class DateTime {
|
|
|
27
27
|
second?: number,
|
|
28
28
|
millisecond?: number,
|
|
29
29
|
);
|
|
30
|
-
/**
|
|
30
|
+
/** tick (밀리초)으로 생성 */
|
|
31
31
|
constructor(tick: number);
|
|
32
|
-
/**
|
|
32
|
+
/** Date 객체로 생성 */
|
|
33
33
|
constructor(date: Date);
|
|
34
34
|
constructor(
|
|
35
35
|
arg1?: number | Date,
|
|
@@ -60,11 +60,11 @@ export class DateTime {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
63
|
+
* 문자열을 파싱하여 DateTime 인스턴스 생성
|
|
64
64
|
*
|
|
65
|
-
* @param str DateTime
|
|
66
|
-
* @returns
|
|
67
|
-
* @throws ArgumentError
|
|
65
|
+
* @param str DateTime 문자열
|
|
66
|
+
* @returns 파싱된 DateTime 인스턴스
|
|
67
|
+
* @throws ArgumentError 지원하지 않는 형식인 경우
|
|
68
68
|
*
|
|
69
69
|
* @example
|
|
70
70
|
* DateTime.parse("2025-01-15 10:30:00") // yyyy-MM-dd HH:mm:ss
|
|
@@ -98,7 +98,7 @@ export class DateTime {
|
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
//
|
|
101
|
+
// 한국어 오전/오후 형식
|
|
102
102
|
const matchKorean =
|
|
103
103
|
/^([0-9]{4})-([0-9]{2})-([0-9]{2}) (오전|오후) ([0-9]{1,2}):([0-9]{2}):([0-9]{2})(\.([0-9]{1,3}))?$/.exec(
|
|
104
104
|
str,
|
|
@@ -147,12 +147,12 @@ export class DateTime {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
throw new ArgumentError(
|
|
150
|
-
|
|
150
|
+
`날짜시간 형식 파싱 실패. 지원 형식: 'yyyy-MM-dd HH:mm:ss', 'yyyyMMddHHmmss', 'yyyy-MM-dd AM/PM HH:mm:ss', ISO 8601`,
|
|
151
151
|
{ input: str },
|
|
152
152
|
);
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
//#region Getters (
|
|
155
|
+
//#region Getters (읽기 전용)
|
|
156
156
|
|
|
157
157
|
get year(): number {
|
|
158
158
|
return this.date.getFullYear();
|
|
@@ -186,7 +186,7 @@ export class DateTime {
|
|
|
186
186
|
return this.date.getTime();
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
/**
|
|
189
|
+
/** 요일 (일요일~토요일: 0~6) */
|
|
190
190
|
get dayOfWeek(): number {
|
|
191
191
|
return this.date.getDay();
|
|
192
192
|
}
|
|
@@ -195,21 +195,22 @@ export class DateTime {
|
|
|
195
195
|
return -this.date.getTimezoneOffset();
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
/**
|
|
198
|
+
/** 날짜시간이 올바르게 설정되었는지 여부 */
|
|
199
199
|
get isValid(): boolean {
|
|
200
200
|
return this.date instanceof Date && !Number.isNaN(this.date.getTime());
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
//#endregion
|
|
204
204
|
|
|
205
|
-
//#region
|
|
205
|
+
//#region 불변 변환 메서드 (새 인스턴스 반환)
|
|
206
206
|
|
|
207
|
-
/**
|
|
207
|
+
/** 지정된 연도로 새 인스턴스 반환 */
|
|
208
208
|
setYear(year: number): DateTime {
|
|
209
|
+
const lastDay = new Date(year, this.month, 0).getDate();
|
|
209
210
|
return new DateTime(
|
|
210
211
|
year,
|
|
211
212
|
this.month,
|
|
212
|
-
this.day,
|
|
213
|
+
Math.min(this.day, lastDay),
|
|
213
214
|
this.hour,
|
|
214
215
|
this.minute,
|
|
215
216
|
this.second,
|
|
@@ -218,10 +219,10 @@ export class DateTime {
|
|
|
218
219
|
}
|
|
219
220
|
|
|
220
221
|
/**
|
|
221
|
-
*
|
|
222
|
-
* @param month
|
|
223
|
-
* @note
|
|
224
|
-
* (
|
|
222
|
+
* 지정된 월로 새 DateTime 인스턴스 반환
|
|
223
|
+
* @param month 설정할 월 (1-12, 범위 밖의 값은 연도에서 조정됨)
|
|
224
|
+
* @note 현재 일이 대상 월의 일수보다 크면 해당 월의 마지막 일로 조정됨
|
|
225
|
+
* (예: 1월 31일에서 setMonth(2) → 2월 28일 또는 29일)
|
|
225
226
|
*/
|
|
226
227
|
setMonth(month: number): DateTime {
|
|
227
228
|
const normalized = normalizeMonth(this.year, month, this.day);
|
|
@@ -237,10 +238,10 @@ export class DateTime {
|
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
/**
|
|
240
|
-
*
|
|
241
|
-
* @param day
|
|
242
|
-
* @note
|
|
243
|
-
* (
|
|
241
|
+
* 지정된 일로 새 DateTime 인스턴스 반환
|
|
242
|
+
* @param day 설정할 일
|
|
243
|
+
* @note 유효한 월 범위를 벗어나는 일은 JavaScript Date 동작에 따라 자동으로 다음/이전 월로 조정됨
|
|
244
|
+
* (예: 1월에 day=32 → 2월 1일)
|
|
244
245
|
*/
|
|
245
246
|
setDay(day: number): DateTime {
|
|
246
247
|
return new DateTime(
|
|
@@ -254,7 +255,7 @@ export class DateTime {
|
|
|
254
255
|
);
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
/**
|
|
258
|
+
/** 지정된 시로 새 인스턴스 반환 */
|
|
258
259
|
setHour(hour: number): DateTime {
|
|
259
260
|
return new DateTime(
|
|
260
261
|
this.year,
|
|
@@ -267,7 +268,7 @@ export class DateTime {
|
|
|
267
268
|
);
|
|
268
269
|
}
|
|
269
270
|
|
|
270
|
-
/**
|
|
271
|
+
/** 지정된 분으로 새 인스턴스 반환 */
|
|
271
272
|
setMinute(minute: number): DateTime {
|
|
272
273
|
return new DateTime(
|
|
273
274
|
this.year,
|
|
@@ -280,7 +281,7 @@ export class DateTime {
|
|
|
280
281
|
);
|
|
281
282
|
}
|
|
282
283
|
|
|
283
|
-
/**
|
|
284
|
+
/** 지정된 초로 새 인스턴스 반환 */
|
|
284
285
|
setSecond(second: number): DateTime {
|
|
285
286
|
return new DateTime(
|
|
286
287
|
this.year,
|
|
@@ -293,7 +294,7 @@ export class DateTime {
|
|
|
293
294
|
);
|
|
294
295
|
}
|
|
295
296
|
|
|
296
|
-
/**
|
|
297
|
+
/** 지정된 밀리초로 새 인스턴스 반환 */
|
|
297
298
|
setMillisecond(millisecond: number): DateTime {
|
|
298
299
|
return new DateTime(
|
|
299
300
|
this.year,
|
|
@@ -308,39 +309,39 @@ export class DateTime {
|
|
|
308
309
|
|
|
309
310
|
//#endregion
|
|
310
311
|
|
|
311
|
-
//#region
|
|
312
|
+
//#region 산술 메서드 (새 인스턴스 반환)
|
|
312
313
|
|
|
313
|
-
/**
|
|
314
|
+
/** 지정된 연수를 더한 새 인스턴스 반환 */
|
|
314
315
|
addYears(years: number): DateTime {
|
|
315
316
|
return this.setYear(this.year + years);
|
|
316
317
|
}
|
|
317
318
|
|
|
318
|
-
/**
|
|
319
|
+
/** 지정된 월수를 더한 새 인스턴스 반환 */
|
|
319
320
|
addMonths(months: number): DateTime {
|
|
320
321
|
return this.setMonth(this.month + months);
|
|
321
322
|
}
|
|
322
323
|
|
|
323
|
-
/**
|
|
324
|
+
/** 지정된 일수를 더한 새 인스턴스 반환 */
|
|
324
325
|
addDays(days: number): DateTime {
|
|
325
326
|
return new DateTime(this.tick + days * 24 * 60 * 60 * 1000);
|
|
326
327
|
}
|
|
327
328
|
|
|
328
|
-
/**
|
|
329
|
+
/** 지정된 시간을 더한 새 인스턴스 반환 */
|
|
329
330
|
addHours(hours: number): DateTime {
|
|
330
331
|
return new DateTime(this.tick + hours * 60 * 60 * 1000);
|
|
331
332
|
}
|
|
332
333
|
|
|
333
|
-
/**
|
|
334
|
+
/** 지정된 분을 더한 새 인스턴스 반환 */
|
|
334
335
|
addMinutes(minutes: number): DateTime {
|
|
335
336
|
return new DateTime(this.tick + minutes * 60 * 1000);
|
|
336
337
|
}
|
|
337
338
|
|
|
338
|
-
/**
|
|
339
|
+
/** 지정된 초를 더한 새 인스턴스 반환 */
|
|
339
340
|
addSeconds(seconds: number): DateTime {
|
|
340
341
|
return new DateTime(this.tick + seconds * 1000);
|
|
341
342
|
}
|
|
342
343
|
|
|
343
|
-
/**
|
|
344
|
+
/** 지정된 밀리초를 더한 새 인스턴스 반환 */
|
|
344
345
|
addMilliseconds(milliseconds: number): DateTime {
|
|
345
346
|
return new DateTime(this.tick + milliseconds);
|
|
346
347
|
}
|
|
@@ -350,9 +351,9 @@ export class DateTime {
|
|
|
350
351
|
//#region Formatting
|
|
351
352
|
|
|
352
353
|
/**
|
|
353
|
-
*
|
|
354
|
-
* @param format
|
|
355
|
-
* @see dtFormat
|
|
354
|
+
* 지정된 형식으로 문자열 변환
|
|
355
|
+
* @param format 형식 문자열
|
|
356
|
+
* @see dtFormat 지원되는 형식 문자열 참조
|
|
356
357
|
*/
|
|
357
358
|
toFormatString(formatStr: string): string {
|
|
358
359
|
return format(formatStr, {
|