@shisyamo4131/air-guard-v2-schemas 2.4.2-dev.6 → 2.4.2-dev.61
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/index.js +9 -0
- package/package.json +45 -47
- package/src/Agreement.js +17 -24
- package/src/AgreementV2.js +185 -0
- package/src/ArrangementNotification.js +8 -8
- package/src/Company.js +162 -25
- package/src/Customer.js +39 -59
- package/src/Employee.js +585 -297
- package/src/Insurance.js +347 -0
- package/src/Operation.js +272 -280
- package/src/OperationBilling.js +126 -192
- package/src/OperationDetail.js +115 -85
- package/src/OperationResult.js +257 -240
- package/src/OperationResultDetail.js +65 -56
- package/src/Site.js +160 -132
- package/src/SiteOperationSchedule.js +185 -241
- package/src/SiteOperationScheduleDetail.js +75 -65
- package/src/SiteOrder.js +18 -29
- package/src/User.js +5 -1
- package/src/WorkTimeBase.js +211 -0
- package/src/WorkingResult.js +83 -255
- package/src/constants/day-type.js +20 -12
- package/src/constants/index.js +4 -0
- package/src/constants/insurance-status.js +15 -0
- package/src/constants/shift-type.js +5 -2
- package/src/errorDefinitions.js +173 -0
- package/src/parts/fieldDefinitions.js +204 -18
- package/src/utils/index.js +20 -8
|
@@ -2,6 +2,10 @@ import {
|
|
|
2
2
|
VALUES as ARRANGEMENT_NOTIFICATION_STATUS_VALUES,
|
|
3
3
|
OPTIONS as ARRANGEMENT_NOTIFICATION_STATUS_OPTIONS,
|
|
4
4
|
} from "../constants/arrangement-notification-status.js";
|
|
5
|
+
import {
|
|
6
|
+
VALUES as BILLING_UNIT_TYPE_VALUES,
|
|
7
|
+
OPTIONS as BILLING_UNIT_TYPE_OPTIONS,
|
|
8
|
+
} from "../constants/billing-unit-type.js";
|
|
5
9
|
import {
|
|
6
10
|
VALUES as BLOOD_TYPE_VALUES,
|
|
7
11
|
OPTIONS as BLOOD_TYPE_OPTIONS,
|
|
@@ -30,7 +34,15 @@ import {
|
|
|
30
34
|
VALUES as GENDER_VALUES,
|
|
31
35
|
OPTIONS as GENDER_OPTIONS,
|
|
32
36
|
} from "../constants/gender.js";
|
|
37
|
+
import {
|
|
38
|
+
VALUES as INSURANCE_STATUS_VALUES,
|
|
39
|
+
OPTIONS as INSURANCE_STATUS_OPTIONS,
|
|
40
|
+
} from "../constants/insurance-status.js";
|
|
33
41
|
import { OPTIONS as PREFECTURES_OPTIONS } from "../constants/prefectures.js";
|
|
42
|
+
import {
|
|
43
|
+
VALUES as PAYMENT_MONTH_VALUES,
|
|
44
|
+
OPTIONS as PAYMENT_MONTH_OPTIONS,
|
|
45
|
+
} from "../constants/payment-month.js";
|
|
34
46
|
import {
|
|
35
47
|
VALUES as SHIFT_TYPE_VALUES,
|
|
36
48
|
OPTIONS as SHIFT_TYPE_OPTIONS,
|
|
@@ -40,6 +52,7 @@ import {
|
|
|
40
52
|
OPTIONS as SITE_STATUS_OPTIONS,
|
|
41
53
|
} from "../constants/site-status.js";
|
|
42
54
|
import CutoffDate from "../utils/CutoffDate.js";
|
|
55
|
+
import { VALIDATION_ERRORS } from "../errorDefinitions.js";
|
|
43
56
|
|
|
44
57
|
export const DEFAULT_WORKING_MINUTES = 480;
|
|
45
58
|
export const DEFAULT_BREAK_MINUTES = 60;
|
|
@@ -47,6 +60,25 @@ export const MINUTES_PER_HOUR = 60;
|
|
|
47
60
|
export const MINUTES_PER_QUARTER_HOUR = 15;
|
|
48
61
|
export const MAX_SCHEDULED_WORKING_MINUTES = 480; // 8時間 * 60分
|
|
49
62
|
|
|
63
|
+
/**
|
|
64
|
+
* フィールド定義のデフォルト値
|
|
65
|
+
* - `air-firebase` が提供する `FireModel (BaseClass)` において、クラスが保有するフィールドの定義および値の検証に使用されます。
|
|
66
|
+
* - `component` プロパティは `air-vuetify` の入力コンポーネント生成の為の属性として使用されます。
|
|
67
|
+
* 但し、required, label, hidden, length は入力コンポーネントの属性としても使用されます。
|
|
68
|
+
* - `validator` の返り値は原則オブジェクトです。文字列を返すこともでき、その文字列がエラーメッセージとして扱われますが多言語対応のためには
|
|
69
|
+
* オブジェクトを返すことを推奨します。
|
|
70
|
+
* 返り値が true/false の場合は、従来通りのバリデーション結果として扱われます。
|
|
71
|
+
* @key {String|Number|Boolean|Object|Array|Date} type - データの型
|
|
72
|
+
* @key {any} default - 既定値
|
|
73
|
+
* @key {String} label - フィールドのラベル
|
|
74
|
+
* @key {Number} length - 入力可能な最大文字数(文字列型の場合)
|
|
75
|
+
* @key {Boolean} required - 入力必須かどうか
|
|
76
|
+
* @key {Boolean} hidden - フィールドをUI上で非表示にするかどうか
|
|
77
|
+
* @key {Function} validator - フィールドの値を検証する関数。引数に値を取り、エラーメッセージを返すか、true/falseで検証結果を返す。
|
|
78
|
+
* @key {Object} component - フィールドに対応するUIコンポーネントの定義
|
|
79
|
+
* @key {String} component.name - 使用するコンポーネントの名前(AirVuetifyコンポーネントのみ指定可能)
|
|
80
|
+
* @key {Object} component.attrs - コンポーネントに渡す属性の定義
|
|
81
|
+
*/
|
|
50
82
|
const defaultDefinition = {
|
|
51
83
|
type: String,
|
|
52
84
|
default: null,
|
|
@@ -54,6 +86,7 @@ const defaultDefinition = {
|
|
|
54
86
|
length: undefined,
|
|
55
87
|
required: undefined,
|
|
56
88
|
hidden: undefined,
|
|
89
|
+
validator: undefined,
|
|
57
90
|
component: {
|
|
58
91
|
name: undefined,
|
|
59
92
|
attrs: {},
|
|
@@ -148,17 +181,36 @@ const generalDefinitions = {
|
|
|
148
181
|
|
|
149
182
|
/** カスタムパーツ(汎用パーツ含む) */
|
|
150
183
|
export const fieldDefinitions = {
|
|
151
|
-
|
|
184
|
+
/*****************************************************************************
|
|
185
|
+
* ARRAY
|
|
186
|
+
*****************************************************************************/
|
|
152
187
|
array: generalDefinitions.array,
|
|
153
|
-
|
|
188
|
+
|
|
189
|
+
/*****************************************************************************
|
|
190
|
+
* CHECK
|
|
191
|
+
*****************************************************************************/
|
|
154
192
|
check: generalDefinitions.check,
|
|
193
|
+
hasPeriodOfStayLimit: {
|
|
194
|
+
...generalDefinitions.check,
|
|
195
|
+
label: "在留期間制限",
|
|
196
|
+
},
|
|
197
|
+
hasWorkRestrictions: {
|
|
198
|
+
...generalDefinitions.check,
|
|
199
|
+
label: "就労制限",
|
|
200
|
+
},
|
|
155
201
|
isForeigner: {
|
|
156
202
|
...generalDefinitions.check,
|
|
157
203
|
label: "外国籍",
|
|
158
204
|
},
|
|
159
|
-
|
|
205
|
+
|
|
206
|
+
/*****************************************************************************
|
|
207
|
+
* CODE
|
|
208
|
+
*****************************************************************************/
|
|
160
209
|
code: generalDefinitions.code,
|
|
161
|
-
|
|
210
|
+
|
|
211
|
+
/*****************************************************************************
|
|
212
|
+
* DATE AT
|
|
213
|
+
*****************************************************************************/
|
|
162
214
|
dateAt: generalDefinitions.dateAt,
|
|
163
215
|
dateOfBirth: {
|
|
164
216
|
...generalDefinitions.dateAt,
|
|
@@ -186,13 +238,17 @@ export const fieldDefinitions = {
|
|
|
186
238
|
label: "退職日",
|
|
187
239
|
default: null, // 2025-12-26 Set default to null
|
|
188
240
|
},
|
|
241
|
+
enrollmentDateAt: {
|
|
242
|
+
...generalDefinitions.dateAt,
|
|
243
|
+
label: "資格取得日",
|
|
244
|
+
default: null,
|
|
245
|
+
},
|
|
189
246
|
// 2025-12-26 Added
|
|
190
247
|
expirationDateAt: {
|
|
191
248
|
...generalDefinitions.dateAt,
|
|
192
249
|
label: "有効期限",
|
|
193
250
|
default: null,
|
|
194
251
|
},
|
|
195
|
-
// 2025-12-26 Added
|
|
196
252
|
issueDateAt: {
|
|
197
253
|
...generalDefinitions.dateAt,
|
|
198
254
|
label: "取得日",
|
|
@@ -209,13 +265,21 @@ export const fieldDefinitions = {
|
|
|
209
265
|
...generalDefinitions.multipleLine,
|
|
210
266
|
label: "備考",
|
|
211
267
|
},
|
|
212
|
-
|
|
268
|
+
|
|
269
|
+
/*****************************************************************************
|
|
270
|
+
* NUMBER
|
|
271
|
+
*****************************************************************************/
|
|
213
272
|
number: generalDefinitions.number,
|
|
214
273
|
breakMinutes: {
|
|
215
274
|
...generalDefinitions.number,
|
|
216
275
|
label: "休憩時間(分)",
|
|
217
276
|
default: DEFAULT_BREAK_MINUTES,
|
|
218
|
-
validator: (v) =>
|
|
277
|
+
validator: (v) => {
|
|
278
|
+
if (v < 0) {
|
|
279
|
+
return VALIDATION_ERRORS.MIN_VALUE_ERROR(0);
|
|
280
|
+
}
|
|
281
|
+
return true;
|
|
282
|
+
},
|
|
219
283
|
component: {
|
|
220
284
|
...generalDefinitions.number.component,
|
|
221
285
|
attrs: {
|
|
@@ -228,7 +292,12 @@ export const fieldDefinitions = {
|
|
|
228
292
|
...generalDefinitions.number,
|
|
229
293
|
label: "残業時間(分)",
|
|
230
294
|
default: 0,
|
|
231
|
-
validator: (v) =>
|
|
295
|
+
validator: (v) => {
|
|
296
|
+
if (v < 0) {
|
|
297
|
+
return VALIDATION_ERRORS.MIN_VALUE_ERROR(0);
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
},
|
|
232
301
|
component: {
|
|
233
302
|
...generalDefinitions.number.component,
|
|
234
303
|
attrs: {
|
|
@@ -241,7 +310,12 @@ export const fieldDefinitions = {
|
|
|
241
310
|
...generalDefinitions.number,
|
|
242
311
|
label: "規定実働時間(分)",
|
|
243
312
|
default: DEFAULT_WORKING_MINUTES,
|
|
244
|
-
validator: (v) =>
|
|
313
|
+
validator: (v) => {
|
|
314
|
+
if (v < 0) {
|
|
315
|
+
return VALIDATION_ERRORS.MIN_VALUE_ERROR(0);
|
|
316
|
+
}
|
|
317
|
+
return true;
|
|
318
|
+
},
|
|
245
319
|
component: {
|
|
246
320
|
...generalDefinitions.number.component,
|
|
247
321
|
attrs: {
|
|
@@ -256,12 +330,24 @@ export const fieldDefinitions = {
|
|
|
256
330
|
...generalDefinitions.number,
|
|
257
331
|
},
|
|
258
332
|
|
|
259
|
-
|
|
333
|
+
/*****************************************************************************
|
|
334
|
+
* ONE LINE
|
|
335
|
+
*****************************************************************************/
|
|
260
336
|
oneLine: generalDefinitions.oneLine,
|
|
337
|
+
abbreviation: {
|
|
338
|
+
...generalDefinitions.oneLine,
|
|
339
|
+
label: "略称",
|
|
340
|
+
length: 20,
|
|
341
|
+
},
|
|
261
342
|
address: {
|
|
262
343
|
...generalDefinitions.oneLine,
|
|
263
344
|
label: "町域名・番地",
|
|
264
|
-
length:
|
|
345
|
+
length: 30,
|
|
346
|
+
},
|
|
347
|
+
branchName: {
|
|
348
|
+
...generalDefinitions.oneLine,
|
|
349
|
+
label: "支店名など",
|
|
350
|
+
length: 20,
|
|
265
351
|
},
|
|
266
352
|
building: {
|
|
267
353
|
...generalDefinitions.oneLine,
|
|
@@ -271,7 +357,23 @@ export const fieldDefinitions = {
|
|
|
271
357
|
city: {
|
|
272
358
|
...generalDefinitions.oneLine,
|
|
273
359
|
label: "市区町村",
|
|
274
|
-
length:
|
|
360
|
+
length: 20,
|
|
361
|
+
},
|
|
362
|
+
companyName: {
|
|
363
|
+
...generalDefinitions.oneLine,
|
|
364
|
+
label: "会社名",
|
|
365
|
+
length: 20,
|
|
366
|
+
},
|
|
367
|
+
companyNameKana: {
|
|
368
|
+
...generalDefinitions.oneLine,
|
|
369
|
+
label: "会社名(カナ)",
|
|
370
|
+
length: 40,
|
|
371
|
+
component: {
|
|
372
|
+
name: generalDefinitions.oneLine.component.name,
|
|
373
|
+
attrs: {
|
|
374
|
+
inputType: "katakana",
|
|
375
|
+
},
|
|
376
|
+
},
|
|
275
377
|
},
|
|
276
378
|
customerId: {
|
|
277
379
|
...generalDefinitions.oneLine,
|
|
@@ -287,6 +389,21 @@ export const fieldDefinitions = {
|
|
|
287
389
|
},
|
|
288
390
|
},
|
|
289
391
|
},
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* 取引先名
|
|
395
|
+
* - 2文字以上最大20文字
|
|
396
|
+
*/
|
|
397
|
+
customerName: {
|
|
398
|
+
...generalDefinitions.oneLine,
|
|
399
|
+
label: "取引先名",
|
|
400
|
+
length: 20,
|
|
401
|
+
component: {
|
|
402
|
+
name: generalDefinitions.oneLine.component.name,
|
|
403
|
+
attrs: { minLength: 2 },
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
|
|
290
407
|
displayName: {
|
|
291
408
|
...generalDefinitions.oneLine,
|
|
292
409
|
label: "表示名",
|
|
@@ -295,7 +412,7 @@ export const fieldDefinitions = {
|
|
|
295
412
|
domicile: {
|
|
296
413
|
...generalDefinitions.oneLine,
|
|
297
414
|
label: "本籍地",
|
|
298
|
-
length:
|
|
415
|
+
length: 50,
|
|
299
416
|
},
|
|
300
417
|
email: {
|
|
301
418
|
...generalDefinitions.oneLine,
|
|
@@ -305,13 +422,14 @@ export const fieldDefinitions = {
|
|
|
305
422
|
name: generalDefinitions.oneLine.component.name,
|
|
306
423
|
attrs: {
|
|
307
424
|
inputType: "email",
|
|
425
|
+
inputmode: "email",
|
|
308
426
|
},
|
|
309
427
|
},
|
|
310
428
|
},
|
|
311
429
|
emergencyContactAddress: {
|
|
312
430
|
...generalDefinitions.oneLine,
|
|
313
431
|
label: "緊急連絡先住所",
|
|
314
|
-
length:
|
|
432
|
+
length: 50,
|
|
315
433
|
},
|
|
316
434
|
emergencyContactName: {
|
|
317
435
|
...generalDefinitions.oneLine,
|
|
@@ -332,6 +450,7 @@ export const fieldDefinitions = {
|
|
|
332
450
|
attrs: {
|
|
333
451
|
counter: true,
|
|
334
452
|
inputType: "tel",
|
|
453
|
+
inputmode: "tel",
|
|
335
454
|
},
|
|
336
455
|
},
|
|
337
456
|
},
|
|
@@ -344,6 +463,7 @@ export const fieldDefinitions = {
|
|
|
344
463
|
attrs: {
|
|
345
464
|
counter: true,
|
|
346
465
|
inputType: "tel",
|
|
466
|
+
inputmode: "tel",
|
|
347
467
|
},
|
|
348
468
|
},
|
|
349
469
|
},
|
|
@@ -375,6 +495,11 @@ export const fieldDefinitions = {
|
|
|
375
495
|
},
|
|
376
496
|
},
|
|
377
497
|
},
|
|
498
|
+
insuranceNumber: {
|
|
499
|
+
...generalDefinitions.oneLine,
|
|
500
|
+
label: "被保険者番号(整理記号)",
|
|
501
|
+
length: 20,
|
|
502
|
+
},
|
|
378
503
|
// 2025-12-26 Added
|
|
379
504
|
issuedBy: {
|
|
380
505
|
...generalDefinitions.oneLine,
|
|
@@ -406,6 +531,7 @@ export const fieldDefinitions = {
|
|
|
406
531
|
attrs: {
|
|
407
532
|
counter: true,
|
|
408
533
|
inputType: "tel",
|
|
534
|
+
inputmode: "tel",
|
|
409
535
|
},
|
|
410
536
|
},
|
|
411
537
|
},
|
|
@@ -467,6 +593,7 @@ export const fieldDefinitions = {
|
|
|
467
593
|
attrs: {
|
|
468
594
|
counter: true,
|
|
469
595
|
inputType: "tel",
|
|
596
|
+
inputmode: "tel",
|
|
470
597
|
},
|
|
471
598
|
},
|
|
472
599
|
},
|
|
@@ -503,7 +630,9 @@ export const fieldDefinitions = {
|
|
|
503
630
|
},
|
|
504
631
|
},
|
|
505
632
|
|
|
506
|
-
|
|
633
|
+
/*****************************************************************************
|
|
634
|
+
* OBJECT
|
|
635
|
+
*****************************************************************************/
|
|
507
636
|
object: generalDefinitions.object,
|
|
508
637
|
|
|
509
638
|
customer: {
|
|
@@ -520,15 +649,23 @@ export const fieldDefinitions = {
|
|
|
520
649
|
},
|
|
521
650
|
},
|
|
522
651
|
},
|
|
652
|
+
employmentInsurance: {
|
|
653
|
+
...generalDefinitions.object,
|
|
654
|
+
label: "雇用保険",
|
|
655
|
+
},
|
|
523
656
|
location: {
|
|
524
657
|
...generalDefinitions.object,
|
|
525
658
|
hidden: true,
|
|
526
659
|
},
|
|
527
660
|
|
|
528
|
-
|
|
661
|
+
/*****************************************************************************
|
|
662
|
+
* RADIO
|
|
663
|
+
*****************************************************************************/
|
|
529
664
|
radio: generalDefinitions.radio,
|
|
530
665
|
|
|
531
|
-
|
|
666
|
+
/*****************************************************************************
|
|
667
|
+
* SELECT
|
|
668
|
+
*****************************************************************************/
|
|
532
669
|
select: generalDefinitions.select,
|
|
533
670
|
arrangementNotificationStatus: {
|
|
534
671
|
...generalDefinitions.select,
|
|
@@ -541,6 +678,18 @@ export const fieldDefinitions = {
|
|
|
541
678
|
},
|
|
542
679
|
},
|
|
543
680
|
},
|
|
681
|
+
/** 請求単位 */
|
|
682
|
+
billingUnitType: {
|
|
683
|
+
...generalDefinitions.select,
|
|
684
|
+
default: BILLING_UNIT_TYPE_VALUES.PER_DAY.value,
|
|
685
|
+
label: "請求単位",
|
|
686
|
+
component: {
|
|
687
|
+
name: generalDefinitions.select.component.name,
|
|
688
|
+
attrs: {
|
|
689
|
+
items: BILLING_UNIT_TYPE_OPTIONS,
|
|
690
|
+
},
|
|
691
|
+
},
|
|
692
|
+
},
|
|
544
693
|
bloodType: {
|
|
545
694
|
...generalDefinitions.select,
|
|
546
695
|
label: "血液型",
|
|
@@ -630,6 +779,39 @@ export const fieldDefinitions = {
|
|
|
630
779
|
},
|
|
631
780
|
},
|
|
632
781
|
},
|
|
782
|
+
insuranceStatus: {
|
|
783
|
+
...generalDefinitions.select,
|
|
784
|
+
default: INSURANCE_STATUS_VALUES.NOT_ENROLLED.value,
|
|
785
|
+
label: "保険状態",
|
|
786
|
+
component: {
|
|
787
|
+
name: generalDefinitions.select.component.name,
|
|
788
|
+
attrs: {
|
|
789
|
+
items: INSURANCE_STATUS_OPTIONS,
|
|
790
|
+
},
|
|
791
|
+
},
|
|
792
|
+
},
|
|
793
|
+
paymentDate: {
|
|
794
|
+
...generalDefinitions.select,
|
|
795
|
+
default: CutoffDate.VALUES[0].value,
|
|
796
|
+
label: "入金サイト(日)",
|
|
797
|
+
component: {
|
|
798
|
+
name: generalDefinitions.select.component.name,
|
|
799
|
+
attrs: {
|
|
800
|
+
items: CutoffDate.OPTIONS,
|
|
801
|
+
},
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
paymentMonth: {
|
|
805
|
+
...generalDefinitions.select,
|
|
806
|
+
default: PAYMENT_MONTH_VALUES[1].value,
|
|
807
|
+
label: "入金サイト(月数)",
|
|
808
|
+
component: {
|
|
809
|
+
name: generalDefinitions.select.component.name,
|
|
810
|
+
attrs: {
|
|
811
|
+
items: PAYMENT_MONTH_OPTIONS,
|
|
812
|
+
},
|
|
813
|
+
},
|
|
814
|
+
},
|
|
633
815
|
prefCode: {
|
|
634
816
|
...generalDefinitions.select,
|
|
635
817
|
label: "都道府県",
|
|
@@ -689,7 +871,7 @@ export const defField = (key, options = {}) => {
|
|
|
689
871
|
|
|
690
872
|
if (!baseConfigSource) {
|
|
691
873
|
console.warn(
|
|
692
|
-
`[parts/fieldDefinitions.js defField] Definition for key "${key}" not found. Using fieldDefinitions.default as base
|
|
874
|
+
`[parts/fieldDefinitions.js defField] Definition for key "${key}" not found. Using fieldDefinitions.default as base.`,
|
|
693
875
|
);
|
|
694
876
|
baseConfigSource = effectiveDefaultDefinition;
|
|
695
877
|
isFallback = true;
|
|
@@ -753,6 +935,10 @@ export const defField = (key, options = {}) => {
|
|
|
753
935
|
if (options.hasOwnProperty("required")) {
|
|
754
936
|
newConfig.required = options.required;
|
|
755
937
|
}
|
|
938
|
+
// validatorの処理: optionsにvalidatorがあれば設定
|
|
939
|
+
if (options.hasOwnProperty("validator")) {
|
|
940
|
+
newConfig.validator = options.validator;
|
|
941
|
+
}
|
|
756
942
|
// `hidden` は options にあればその値、なければ newConfig の値 (baseConfig または defaultDefinition 由来) を維持
|
|
757
943
|
// defaultDefinition.hidden は undefined なので、指定がなければ undefined のままになる
|
|
758
944
|
if (options.hasOwnProperty("hidden")) {
|
package/src/utils/index.js
CHANGED
|
@@ -15,14 +15,14 @@ export function getDateAt(date, time, dateOffset = 0) {
|
|
|
15
15
|
// If date is not null/undefined and is not a string or Date, throw an error
|
|
16
16
|
if (date != null && !(typeof date === "string" || date instanceof Date)) {
|
|
17
17
|
throw new Error(
|
|
18
|
-
`[getDateAt] Invalid date type. Expected string or Date, got ${typeof date}
|
|
18
|
+
`[getDateAt] Invalid date type. Expected string or Date, got ${typeof date}`,
|
|
19
19
|
);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// If time is not null and is not a string, throw an error
|
|
23
23
|
if (time != null && typeof time !== "string") {
|
|
24
24
|
throw new Error(
|
|
25
|
-
`[getDateAt] Invalid time type. Expected string, got ${typeof time}
|
|
25
|
+
`[getDateAt] Invalid time type. Expected string, got ${typeof time}`,
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -31,18 +31,30 @@ export function getDateAt(date, time, dateOffset = 0) {
|
|
|
31
31
|
const [hour, minute] = time ? time.split(":").map(Number) : [0, 0];
|
|
32
32
|
if (isNaN(hour) || isNaN(minute)) {
|
|
33
33
|
throw new Error(
|
|
34
|
-
`[getDateAt] Invalid time format. Expected HH:MM, got ${time}
|
|
34
|
+
`[getDateAt] Invalid time format. Expected HH:MM, got ${time}`,
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// If date is not provided, use the current date
|
|
39
|
-
const
|
|
39
|
+
const baseDate = new Date(date || Date.now());
|
|
40
40
|
|
|
41
|
-
// JST
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
// 入力日時から JST の日付成分を取得してから、JST時刻を合成する。
|
|
42
|
+
// これにより、UTC日付境界を跨ぐケースでも期待通りの JST 日付を保てる。
|
|
43
|
+
const jstDate = new Date(baseDate.getTime() + 9 * 60 * 60 * 1000);
|
|
44
|
+
const year = jstDate.getUTCFullYear();
|
|
45
|
+
const month = jstDate.getUTCMonth();
|
|
46
|
+
const day = jstDate.getUTCDate();
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
const utcMillis = Date.UTC(
|
|
49
|
+
year,
|
|
50
|
+
month,
|
|
51
|
+
day + dateOffset,
|
|
52
|
+
hour - 9,
|
|
53
|
+
minute,
|
|
54
|
+
0,
|
|
55
|
+
0,
|
|
56
|
+
);
|
|
57
|
+
return new Date(utcMillis);
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
export { ContextualError } from "./ContextualError.js";
|