@fileverse-dev/formulajs 4.4.34 → 4.4.36
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/lib/browser/formula.js +38 -41
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +36 -204
- package/lib/esm/index.mjs +36 -204
- package/package.json +1 -1
- package/types/cjs/index.d.cts +3 -3
- package/types/esm/index.d.mts +3 -3
package/lib/cjs/index.cjs
CHANGED
|
@@ -8104,6 +8104,18 @@ const WEEKEND_TYPES = [
|
|
|
8104
8104
|
[6, 6]
|
|
8105
8105
|
];
|
|
8106
8106
|
|
|
8107
|
+
const datePartition = (date) => {
|
|
8108
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8109
|
+
|
|
8110
|
+
const day = pad(date.getDate());
|
|
8111
|
+
const month = pad(date.getMonth() + 1);
|
|
8112
|
+
const year = date.getFullYear();
|
|
8113
|
+
const hours = pad(date.getHours());
|
|
8114
|
+
const minutes = pad(date.getMinutes());
|
|
8115
|
+
const seconds = pad(date.getSeconds());
|
|
8116
|
+
return { day, month, year, hours, minutes, seconds };
|
|
8117
|
+
};
|
|
8118
|
+
|
|
8107
8119
|
/**
|
|
8108
8120
|
* Returns the serial number of a particular date.
|
|
8109
8121
|
*
|
|
@@ -8129,10 +8141,8 @@ function DATE(year, month, day) {
|
|
|
8129
8141
|
if (result.getFullYear() < 0) {
|
|
8130
8142
|
result = num;
|
|
8131
8143
|
}
|
|
8132
|
-
|
|
8133
|
-
const dayResult =
|
|
8134
|
-
const monthResult = pad(result.getMonth() + 1);
|
|
8135
|
-
const yearResult = result.getFullYear();
|
|
8144
|
+
|
|
8145
|
+
const { day: dayResult, month: monthResult, year: yearResult } = datePartition(result);
|
|
8136
8146
|
result = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8137
8147
|
}
|
|
8138
8148
|
|
|
@@ -8244,7 +8254,7 @@ function DATEVALUE(date_text) {
|
|
|
8244
8254
|
|
|
8245
8255
|
const dateValue = new Date(date_text);
|
|
8246
8256
|
|
|
8247
|
-
return
|
|
8257
|
+
return dateToSerial(dateValue);
|
|
8248
8258
|
}
|
|
8249
8259
|
|
|
8250
8260
|
/**
|
|
@@ -8396,10 +8406,7 @@ function EDATE(start_date, months) {
|
|
|
8396
8406
|
|
|
8397
8407
|
|
|
8398
8408
|
let widthoutSerial = start_date;
|
|
8399
|
-
const
|
|
8400
|
-
const dayResult = pad(widthoutSerial.getDate());
|
|
8401
|
-
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8402
|
-
const yearResult = widthoutSerial.getFullYear();
|
|
8409
|
+
const { day: dayResult, month: monthResult, year: yearResult } = datePartition(widthoutSerial);
|
|
8403
8410
|
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8404
8411
|
|
|
8405
8412
|
return returnSerial ? dateToSerial(start_date) : widthoutSerial
|
|
@@ -8431,178 +8438,16 @@ function EOMONTH(start_date, months) {
|
|
|
8431
8438
|
|
|
8432
8439
|
|
|
8433
8440
|
let widthoutSerial = eoMonth;
|
|
8434
|
-
const
|
|
8435
|
-
const dayResult = pad(widthoutSerial.getDate());
|
|
8436
|
-
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8437
|
-
const yearResult = widthoutSerial.getFullYear();
|
|
8441
|
+
const { day: dayResult, month: monthResult, year: yearResult } = datePartition(widthoutSerial);
|
|
8438
8442
|
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8439
8443
|
|
|
8440
8444
|
return returnSerial ? dateToSerial(eoMonth) : widthoutSerial
|
|
8441
8445
|
}
|
|
8442
8446
|
|
|
8443
|
-
// export function networkDaysIntl(startDate, endDate, weekend = 1, holidays = []) {
|
|
8444
|
-
// // Normalize input dates (strip time part)
|
|
8445
|
-
// const normalize = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8446
|
-
// startDate = normalize(startDate);
|
|
8447
|
-
// endDate = normalize(endDate);
|
|
8448
|
-
|
|
8449
|
-
// // Google Sheets weekend mappings
|
|
8450
|
-
// const weekendMaps = {
|
|
8451
|
-
// 1: [6, 0], // Sat, Sun
|
|
8452
|
-
// 2: [0, 1], // Sun, Mon
|
|
8453
|
-
// 3: [1, 2], // Mon, Tue
|
|
8454
|
-
// 4: [2, 3], // Tue, Wed
|
|
8455
|
-
// 5: [3, 4], // Wed, Thu
|
|
8456
|
-
// 6: [4, 5], // Thu, Fri
|
|
8457
|
-
// 7: [5, 6], // Fri, Sat
|
|
8458
|
-
|
|
8459
|
-
// // Single-day weekend codes
|
|
8460
|
-
// 11: [0], // Sunday
|
|
8461
|
-
// 12: [1], // Monday
|
|
8462
|
-
// 13: [2], // Tuesday
|
|
8463
|
-
// 14: [3], // Wednesday
|
|
8464
|
-
// 15: [4], // Thursday
|
|
8465
|
-
// 16: [5], // Friday
|
|
8466
|
-
// 17: [6], // Saturday
|
|
8467
|
-
// };
|
|
8468
|
-
|
|
8469
|
-
// let weekendDays = [];
|
|
8470
|
-
|
|
8471
|
-
// // If weekend is a 7-char mask like "0000011"
|
|
8472
|
-
// if (typeof weekend === "string" && weekend.length === 7) {
|
|
8473
|
-
// weekendDays = weekend
|
|
8474
|
-
// .split("")
|
|
8475
|
-
// .map((ch, i) => (ch === "1" ? i : null))
|
|
8476
|
-
// .filter((v) => v !== null);
|
|
8477
|
-
// } else {
|
|
8478
|
-
// weekendDays = weekendMaps[weekend] || weekendMaps[1];
|
|
8479
|
-
// }
|
|
8480
|
-
|
|
8481
|
-
// // Normalize and convert holidays into timestamps
|
|
8482
|
-
// const holidaySet = new Set(
|
|
8483
|
-
// holidays.map((d) => normalize(d).getTime())
|
|
8484
|
-
// );
|
|
8485
|
-
|
|
8486
|
-
// let count = 0;
|
|
8487
|
-
// let current = new Date(startDate);
|
|
8488
|
-
|
|
8489
|
-
// while (current <= endDate) {
|
|
8490
|
-
// const day = current.getDay(); // 0=Sun ... 6=Sat
|
|
8491
|
-
// const ts = current.getTime();
|
|
8492
|
-
|
|
8493
|
-
// const isWeekend = weekendDays.includes(day);
|
|
8494
|
-
// const isHoliday = holidaySet.has(ts);
|
|
8495
|
-
|
|
8496
|
-
// if (!isWeekend && !isHoliday) {
|
|
8497
|
-
// count++;
|
|
8498
|
-
// }
|
|
8499
|
-
|
|
8500
|
-
// current.setDate(current.getDate() + 1);
|
|
8501
|
-
// }
|
|
8502
|
-
|
|
8503
|
-
// return count;
|
|
8504
|
-
// }
|
|
8505
|
-
|
|
8506
|
-
// export function networkDays(startDate, endDate, holidays = []) {
|
|
8507
|
-
// // Normalize date → remove time part
|
|
8508
|
-
// const normalize = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8509
|
-
|
|
8510
|
-
// startDate = normalize(startDate);
|
|
8511
|
-
// endDate = normalize(endDate);
|
|
8512
|
-
|
|
8513
|
-
// // Convert holidays into a Set for O(1) lookup
|
|
8514
|
-
// const holidaySet = new Set(
|
|
8515
|
-
// holidays.map((d) => normalize(d).getTime())
|
|
8516
|
-
// );
|
|
8517
|
-
|
|
8518
|
-
// let count = 0;
|
|
8519
|
-
// let current = new Date(startDate);
|
|
8520
|
-
|
|
8521
|
-
// while (current <= endDate) {
|
|
8522
|
-
// const day = current.getDay(); // 0=Sun ... 6=Sat
|
|
8523
|
-
// const ts = current.getTime();
|
|
8524
|
-
|
|
8525
|
-
// const isWeekend = (day === 0 || day === 6); // Sun or Sat
|
|
8526
|
-
// const isHoliday = holidaySet.has(ts);
|
|
8527
|
-
|
|
8528
|
-
// if (!isWeekend && !isHoliday) {
|
|
8529
|
-
// count++;
|
|
8530
|
-
// }
|
|
8531
|
-
|
|
8532
|
-
// // move to next day
|
|
8533
|
-
// current.setDate(current.getDate() + 1);
|
|
8534
|
-
// }
|
|
8535
|
-
|
|
8536
|
-
// return count;
|
|
8537
|
-
// }
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
// export function workdayIntl(startDate, numDays, weekend = 1, holidays = []) {
|
|
8541
|
-
// // Normalize dates to midnight
|
|
8542
|
-
// const normalize = (d) =>
|
|
8543
|
-
// new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8544
|
-
// startDate = normalize(startDate);
|
|
8545
|
-
|
|
8546
|
-
// // Weekend mapping from Google Sheets
|
|
8547
|
-
// const weekendMaps = {
|
|
8548
|
-
// 1: [6, 0], // Sat, Sun
|
|
8549
|
-
// 2: [0, 1], // Sun, Mon
|
|
8550
|
-
// 3: [1, 2], // Mon, Tue
|
|
8551
|
-
// 4: [2, 3], // Tue, Wed
|
|
8552
|
-
// 5: [3, 4], // Wed, Thu
|
|
8553
|
-
// 6: [4, 5], // Thu, Fri
|
|
8554
|
-
// 7: [5, 6], // Fri, Sat
|
|
8555
|
-
|
|
8556
|
-
// // Single-day weekend codes
|
|
8557
|
-
// 11: [0], // Sun
|
|
8558
|
-
// 12: [1], // Mon
|
|
8559
|
-
// 13: [2], // Tue
|
|
8560
|
-
// 14: [3], // Wed
|
|
8561
|
-
// 15: [4], // Thu
|
|
8562
|
-
// 16: [5], // Fri
|
|
8563
|
-
// 17: [6] // Sat
|
|
8564
|
-
// };
|
|
8565
|
-
|
|
8566
|
-
// let weekendDays = [];
|
|
8567
|
-
|
|
8568
|
-
// // If weekend is mask string like "0000011"
|
|
8569
|
-
// if (typeof weekend === "string" && weekend.length === 7) {
|
|
8570
|
-
// weekendDays = weekend
|
|
8571
|
-
// .split("")
|
|
8572
|
-
// .map((ch, i) => (ch === "1" ? i : null))
|
|
8573
|
-
// .filter((v) => v !== null);
|
|
8574
|
-
// } else {
|
|
8575
|
-
// weekendDays = weekendMaps[weekend] || weekendMaps[1];
|
|
8576
|
-
// }
|
|
8577
|
-
|
|
8578
|
-
// // Holidays → normalize → Set for fast lookup
|
|
8579
|
-
// const holidaySet = new Set(
|
|
8580
|
-
// holidays.map((h) => normalize(h).getTime())
|
|
8581
|
-
// );
|
|
8582
|
-
|
|
8583
|
-
// let current = new Date(startDate);
|
|
8584
|
-
// const direction = numDays >= 0 ? 1 : -1;
|
|
8585
|
-
|
|
8586
|
-
// let daysRemaining = Math.abs(numDays);
|
|
8587
|
-
|
|
8588
|
-
// while (daysRemaining > 0) {
|
|
8589
|
-
// current.setDate(current.getDate() + direction);
|
|
8590
|
-
|
|
8591
|
-
// const day = current.getDay();
|
|
8592
|
-
// const ts = current.getTime();
|
|
8593
|
-
|
|
8594
|
-
// const isWeekend = weekendDays.includes(day);
|
|
8595
|
-
// const isHoliday = holidaySet.has(ts);
|
|
8596
|
-
|
|
8597
|
-
// if (!isWeekend && !isHoliday) {
|
|
8598
|
-
// daysRemaining--;
|
|
8599
|
-
// }
|
|
8600
|
-
// }
|
|
8601
|
-
|
|
8602
|
-
// return current;
|
|
8603
|
-
// }
|
|
8604
|
-
|
|
8605
8447
|
function EPOCHTODATE(timestamp, timeUnit = 1) {
|
|
8448
|
+
if (isNaN(timestamp)) {
|
|
8449
|
+
return num;
|
|
8450
|
+
}
|
|
8606
8451
|
let ms;
|
|
8607
8452
|
|
|
8608
8453
|
switch (timeUnit) {
|
|
@@ -8622,35 +8467,33 @@ function EPOCHTODATE(timestamp, timeUnit = 1) {
|
|
|
8622
8467
|
throw new Error("Invalid time_unit. Use 1 (sec), 2 (ms), or 3 (µs).");
|
|
8623
8468
|
}
|
|
8624
8469
|
|
|
8625
|
-
|
|
8470
|
+
const d = new Date(ms);
|
|
8471
|
+
|
|
8472
|
+
const { day, month, year, hours, minutes, seconds } = datePartition(d);
|
|
8473
|
+
|
|
8474
|
+
return `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`
|
|
8626
8475
|
}
|
|
8627
8476
|
|
|
8628
8477
|
function SEQUENCE(rows, columns = 1, start = 1, step = 1) {
|
|
8629
8478
|
const result = [];
|
|
8630
8479
|
|
|
8631
|
-
const
|
|
8480
|
+
const isDateInput = (val) => {
|
|
8481
|
+
if (val instanceof Date) return true;
|
|
8482
|
+
if (typeof val === "string" && !isNaN(Date.parse(val))) return true;
|
|
8483
|
+
return false;
|
|
8484
|
+
};
|
|
8632
8485
|
|
|
8633
|
-
|
|
8634
|
-
const normalizeDate = (d) =>
|
|
8635
|
-
new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8486
|
+
const isDate = isDateInput(start);
|
|
8636
8487
|
|
|
8637
|
-
if (isDate) start =
|
|
8488
|
+
if (isDate) start = DATEVALUE(start);
|
|
8638
8489
|
|
|
8639
8490
|
for (let r = 0; r < rows; r++) {
|
|
8640
8491
|
const row = [];
|
|
8641
8492
|
|
|
8642
8493
|
for (let c = 0; c < columns; c++) {
|
|
8643
|
-
const index = r * columns + c;
|
|
8494
|
+
const index = r * columns + c;
|
|
8644
8495
|
|
|
8645
|
-
if (isDate) {
|
|
8646
|
-
// Date sequence → step is in DAYS (Google Sheets behavior)
|
|
8647
|
-
const d = new Date(start);
|
|
8648
|
-
d.setDate(start.getDate() + index * step);
|
|
8649
|
-
row.push(d);
|
|
8650
|
-
} else {
|
|
8651
|
-
// Number sequence
|
|
8652
8496
|
row.push(start + index * step);
|
|
8653
|
-
}
|
|
8654
8497
|
}
|
|
8655
8498
|
|
|
8656
8499
|
result.push(row);
|
|
@@ -8856,16 +8699,7 @@ const NETWORKDAYS_INTL = NETWORKDAYS.INTL;
|
|
|
8856
8699
|
*/
|
|
8857
8700
|
function NOW() {
|
|
8858
8701
|
const d = new Date();
|
|
8859
|
-
const
|
|
8860
|
-
|
|
8861
|
-
const day = pad(d.getDate());
|
|
8862
|
-
const month = pad(d.getMonth() + 1);
|
|
8863
|
-
const year = d.getFullYear();
|
|
8864
|
-
|
|
8865
|
-
const hours = pad(d.getHours());
|
|
8866
|
-
const minutes = pad(d.getMinutes());
|
|
8867
|
-
const seconds = pad(d.getSeconds());
|
|
8868
|
-
|
|
8702
|
+
const { day, month, year, hours, minutes, seconds } = datePartition(d);
|
|
8869
8703
|
return returnSerial ? dateToSerial(d) : `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`
|
|
8870
8704
|
}
|
|
8871
8705
|
|
|
@@ -9233,11 +9067,9 @@ function YEARFRAC(start_date, end_date, basis) {
|
|
|
9233
9067
|
}
|
|
9234
9068
|
|
|
9235
9069
|
|
|
9236
|
-
// const start = new Date(2025, 0, 1); // Jan 1 2025
|
|
9237
|
-
// const end = new Date(2025, 11, 31); // Dec 31 2025
|
|
9238
9070
|
|
|
9239
|
-
// const
|
|
9240
|
-
// console.log(
|
|
9071
|
+
// const r = SEQUENCE(2, 1, DATE(2025,1,1),1);
|
|
9072
|
+
// console.log(r);
|
|
9241
9073
|
|
|
9242
9074
|
function isValidBinaryNumber(number) {
|
|
9243
9075
|
return /^[01]{1,10}$/.test(number)
|
package/lib/esm/index.mjs
CHANGED
|
@@ -8102,6 +8102,18 @@ const WEEKEND_TYPES = [
|
|
|
8102
8102
|
[6, 6]
|
|
8103
8103
|
];
|
|
8104
8104
|
|
|
8105
|
+
const datePartition = (date) => {
|
|
8106
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8107
|
+
|
|
8108
|
+
const day = pad(date.getDate());
|
|
8109
|
+
const month = pad(date.getMonth() + 1);
|
|
8110
|
+
const year = date.getFullYear();
|
|
8111
|
+
const hours = pad(date.getHours());
|
|
8112
|
+
const minutes = pad(date.getMinutes());
|
|
8113
|
+
const seconds = pad(date.getSeconds());
|
|
8114
|
+
return { day, month, year, hours, minutes, seconds };
|
|
8115
|
+
};
|
|
8116
|
+
|
|
8105
8117
|
/**
|
|
8106
8118
|
* Returns the serial number of a particular date.
|
|
8107
8119
|
*
|
|
@@ -8127,10 +8139,8 @@ function DATE(year, month, day) {
|
|
|
8127
8139
|
if (result.getFullYear() < 0) {
|
|
8128
8140
|
result = num;
|
|
8129
8141
|
}
|
|
8130
|
-
|
|
8131
|
-
const dayResult =
|
|
8132
|
-
const monthResult = pad(result.getMonth() + 1);
|
|
8133
|
-
const yearResult = result.getFullYear();
|
|
8142
|
+
|
|
8143
|
+
const { day: dayResult, month: monthResult, year: yearResult } = datePartition(result);
|
|
8134
8144
|
result = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8135
8145
|
}
|
|
8136
8146
|
|
|
@@ -8242,7 +8252,7 @@ function DATEVALUE(date_text) {
|
|
|
8242
8252
|
|
|
8243
8253
|
const dateValue = new Date(date_text);
|
|
8244
8254
|
|
|
8245
|
-
return
|
|
8255
|
+
return dateToSerial(dateValue);
|
|
8246
8256
|
}
|
|
8247
8257
|
|
|
8248
8258
|
/**
|
|
@@ -8394,10 +8404,7 @@ function EDATE(start_date, months) {
|
|
|
8394
8404
|
|
|
8395
8405
|
|
|
8396
8406
|
let widthoutSerial = start_date;
|
|
8397
|
-
const
|
|
8398
|
-
const dayResult = pad(widthoutSerial.getDate());
|
|
8399
|
-
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8400
|
-
const yearResult = widthoutSerial.getFullYear();
|
|
8407
|
+
const { day: dayResult, month: monthResult, year: yearResult } = datePartition(widthoutSerial);
|
|
8401
8408
|
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8402
8409
|
|
|
8403
8410
|
return returnSerial ? dateToSerial(start_date) : widthoutSerial
|
|
@@ -8429,178 +8436,16 @@ function EOMONTH(start_date, months) {
|
|
|
8429
8436
|
|
|
8430
8437
|
|
|
8431
8438
|
let widthoutSerial = eoMonth;
|
|
8432
|
-
const
|
|
8433
|
-
const dayResult = pad(widthoutSerial.getDate());
|
|
8434
|
-
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8435
|
-
const yearResult = widthoutSerial.getFullYear();
|
|
8439
|
+
const { day: dayResult, month: monthResult, year: yearResult } = datePartition(widthoutSerial);
|
|
8436
8440
|
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8437
8441
|
|
|
8438
8442
|
return returnSerial ? dateToSerial(eoMonth) : widthoutSerial
|
|
8439
8443
|
}
|
|
8440
8444
|
|
|
8441
|
-
// export function networkDaysIntl(startDate, endDate, weekend = 1, holidays = []) {
|
|
8442
|
-
// // Normalize input dates (strip time part)
|
|
8443
|
-
// const normalize = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8444
|
-
// startDate = normalize(startDate);
|
|
8445
|
-
// endDate = normalize(endDate);
|
|
8446
|
-
|
|
8447
|
-
// // Google Sheets weekend mappings
|
|
8448
|
-
// const weekendMaps = {
|
|
8449
|
-
// 1: [6, 0], // Sat, Sun
|
|
8450
|
-
// 2: [0, 1], // Sun, Mon
|
|
8451
|
-
// 3: [1, 2], // Mon, Tue
|
|
8452
|
-
// 4: [2, 3], // Tue, Wed
|
|
8453
|
-
// 5: [3, 4], // Wed, Thu
|
|
8454
|
-
// 6: [4, 5], // Thu, Fri
|
|
8455
|
-
// 7: [5, 6], // Fri, Sat
|
|
8456
|
-
|
|
8457
|
-
// // Single-day weekend codes
|
|
8458
|
-
// 11: [0], // Sunday
|
|
8459
|
-
// 12: [1], // Monday
|
|
8460
|
-
// 13: [2], // Tuesday
|
|
8461
|
-
// 14: [3], // Wednesday
|
|
8462
|
-
// 15: [4], // Thursday
|
|
8463
|
-
// 16: [5], // Friday
|
|
8464
|
-
// 17: [6], // Saturday
|
|
8465
|
-
// };
|
|
8466
|
-
|
|
8467
|
-
// let weekendDays = [];
|
|
8468
|
-
|
|
8469
|
-
// // If weekend is a 7-char mask like "0000011"
|
|
8470
|
-
// if (typeof weekend === "string" && weekend.length === 7) {
|
|
8471
|
-
// weekendDays = weekend
|
|
8472
|
-
// .split("")
|
|
8473
|
-
// .map((ch, i) => (ch === "1" ? i : null))
|
|
8474
|
-
// .filter((v) => v !== null);
|
|
8475
|
-
// } else {
|
|
8476
|
-
// weekendDays = weekendMaps[weekend] || weekendMaps[1];
|
|
8477
|
-
// }
|
|
8478
|
-
|
|
8479
|
-
// // Normalize and convert holidays into timestamps
|
|
8480
|
-
// const holidaySet = new Set(
|
|
8481
|
-
// holidays.map((d) => normalize(d).getTime())
|
|
8482
|
-
// );
|
|
8483
|
-
|
|
8484
|
-
// let count = 0;
|
|
8485
|
-
// let current = new Date(startDate);
|
|
8486
|
-
|
|
8487
|
-
// while (current <= endDate) {
|
|
8488
|
-
// const day = current.getDay(); // 0=Sun ... 6=Sat
|
|
8489
|
-
// const ts = current.getTime();
|
|
8490
|
-
|
|
8491
|
-
// const isWeekend = weekendDays.includes(day);
|
|
8492
|
-
// const isHoliday = holidaySet.has(ts);
|
|
8493
|
-
|
|
8494
|
-
// if (!isWeekend && !isHoliday) {
|
|
8495
|
-
// count++;
|
|
8496
|
-
// }
|
|
8497
|
-
|
|
8498
|
-
// current.setDate(current.getDate() + 1);
|
|
8499
|
-
// }
|
|
8500
|
-
|
|
8501
|
-
// return count;
|
|
8502
|
-
// }
|
|
8503
|
-
|
|
8504
|
-
// export function networkDays(startDate, endDate, holidays = []) {
|
|
8505
|
-
// // Normalize date → remove time part
|
|
8506
|
-
// const normalize = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8507
|
-
|
|
8508
|
-
// startDate = normalize(startDate);
|
|
8509
|
-
// endDate = normalize(endDate);
|
|
8510
|
-
|
|
8511
|
-
// // Convert holidays into a Set for O(1) lookup
|
|
8512
|
-
// const holidaySet = new Set(
|
|
8513
|
-
// holidays.map((d) => normalize(d).getTime())
|
|
8514
|
-
// );
|
|
8515
|
-
|
|
8516
|
-
// let count = 0;
|
|
8517
|
-
// let current = new Date(startDate);
|
|
8518
|
-
|
|
8519
|
-
// while (current <= endDate) {
|
|
8520
|
-
// const day = current.getDay(); // 0=Sun ... 6=Sat
|
|
8521
|
-
// const ts = current.getTime();
|
|
8522
|
-
|
|
8523
|
-
// const isWeekend = (day === 0 || day === 6); // Sun or Sat
|
|
8524
|
-
// const isHoliday = holidaySet.has(ts);
|
|
8525
|
-
|
|
8526
|
-
// if (!isWeekend && !isHoliday) {
|
|
8527
|
-
// count++;
|
|
8528
|
-
// }
|
|
8529
|
-
|
|
8530
|
-
// // move to next day
|
|
8531
|
-
// current.setDate(current.getDate() + 1);
|
|
8532
|
-
// }
|
|
8533
|
-
|
|
8534
|
-
// return count;
|
|
8535
|
-
// }
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
// export function workdayIntl(startDate, numDays, weekend = 1, holidays = []) {
|
|
8539
|
-
// // Normalize dates to midnight
|
|
8540
|
-
// const normalize = (d) =>
|
|
8541
|
-
// new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8542
|
-
// startDate = normalize(startDate);
|
|
8543
|
-
|
|
8544
|
-
// // Weekend mapping from Google Sheets
|
|
8545
|
-
// const weekendMaps = {
|
|
8546
|
-
// 1: [6, 0], // Sat, Sun
|
|
8547
|
-
// 2: [0, 1], // Sun, Mon
|
|
8548
|
-
// 3: [1, 2], // Mon, Tue
|
|
8549
|
-
// 4: [2, 3], // Tue, Wed
|
|
8550
|
-
// 5: [3, 4], // Wed, Thu
|
|
8551
|
-
// 6: [4, 5], // Thu, Fri
|
|
8552
|
-
// 7: [5, 6], // Fri, Sat
|
|
8553
|
-
|
|
8554
|
-
// // Single-day weekend codes
|
|
8555
|
-
// 11: [0], // Sun
|
|
8556
|
-
// 12: [1], // Mon
|
|
8557
|
-
// 13: [2], // Tue
|
|
8558
|
-
// 14: [3], // Wed
|
|
8559
|
-
// 15: [4], // Thu
|
|
8560
|
-
// 16: [5], // Fri
|
|
8561
|
-
// 17: [6] // Sat
|
|
8562
|
-
// };
|
|
8563
|
-
|
|
8564
|
-
// let weekendDays = [];
|
|
8565
|
-
|
|
8566
|
-
// // If weekend is mask string like "0000011"
|
|
8567
|
-
// if (typeof weekend === "string" && weekend.length === 7) {
|
|
8568
|
-
// weekendDays = weekend
|
|
8569
|
-
// .split("")
|
|
8570
|
-
// .map((ch, i) => (ch === "1" ? i : null))
|
|
8571
|
-
// .filter((v) => v !== null);
|
|
8572
|
-
// } else {
|
|
8573
|
-
// weekendDays = weekendMaps[weekend] || weekendMaps[1];
|
|
8574
|
-
// }
|
|
8575
|
-
|
|
8576
|
-
// // Holidays → normalize → Set for fast lookup
|
|
8577
|
-
// const holidaySet = new Set(
|
|
8578
|
-
// holidays.map((h) => normalize(h).getTime())
|
|
8579
|
-
// );
|
|
8580
|
-
|
|
8581
|
-
// let current = new Date(startDate);
|
|
8582
|
-
// const direction = numDays >= 0 ? 1 : -1;
|
|
8583
|
-
|
|
8584
|
-
// let daysRemaining = Math.abs(numDays);
|
|
8585
|
-
|
|
8586
|
-
// while (daysRemaining > 0) {
|
|
8587
|
-
// current.setDate(current.getDate() + direction);
|
|
8588
|
-
|
|
8589
|
-
// const day = current.getDay();
|
|
8590
|
-
// const ts = current.getTime();
|
|
8591
|
-
|
|
8592
|
-
// const isWeekend = weekendDays.includes(day);
|
|
8593
|
-
// const isHoliday = holidaySet.has(ts);
|
|
8594
|
-
|
|
8595
|
-
// if (!isWeekend && !isHoliday) {
|
|
8596
|
-
// daysRemaining--;
|
|
8597
|
-
// }
|
|
8598
|
-
// }
|
|
8599
|
-
|
|
8600
|
-
// return current;
|
|
8601
|
-
// }
|
|
8602
|
-
|
|
8603
8445
|
function EPOCHTODATE(timestamp, timeUnit = 1) {
|
|
8446
|
+
if (isNaN(timestamp)) {
|
|
8447
|
+
return num;
|
|
8448
|
+
}
|
|
8604
8449
|
let ms;
|
|
8605
8450
|
|
|
8606
8451
|
switch (timeUnit) {
|
|
@@ -8620,35 +8465,33 @@ function EPOCHTODATE(timestamp, timeUnit = 1) {
|
|
|
8620
8465
|
throw new Error("Invalid time_unit. Use 1 (sec), 2 (ms), or 3 (µs).");
|
|
8621
8466
|
}
|
|
8622
8467
|
|
|
8623
|
-
|
|
8468
|
+
const d = new Date(ms);
|
|
8469
|
+
|
|
8470
|
+
const { day, month, year, hours, minutes, seconds } = datePartition(d);
|
|
8471
|
+
|
|
8472
|
+
return `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`
|
|
8624
8473
|
}
|
|
8625
8474
|
|
|
8626
8475
|
function SEQUENCE(rows, columns = 1, start = 1, step = 1) {
|
|
8627
8476
|
const result = [];
|
|
8628
8477
|
|
|
8629
|
-
const
|
|
8478
|
+
const isDateInput = (val) => {
|
|
8479
|
+
if (val instanceof Date) return true;
|
|
8480
|
+
if (typeof val === "string" && !isNaN(Date.parse(val))) return true;
|
|
8481
|
+
return false;
|
|
8482
|
+
};
|
|
8630
8483
|
|
|
8631
|
-
|
|
8632
|
-
const normalizeDate = (d) =>
|
|
8633
|
-
new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8484
|
+
const isDate = isDateInput(start);
|
|
8634
8485
|
|
|
8635
|
-
if (isDate) start =
|
|
8486
|
+
if (isDate) start = DATEVALUE(start);
|
|
8636
8487
|
|
|
8637
8488
|
for (let r = 0; r < rows; r++) {
|
|
8638
8489
|
const row = [];
|
|
8639
8490
|
|
|
8640
8491
|
for (let c = 0; c < columns; c++) {
|
|
8641
|
-
const index = r * columns + c;
|
|
8492
|
+
const index = r * columns + c;
|
|
8642
8493
|
|
|
8643
|
-
if (isDate) {
|
|
8644
|
-
// Date sequence → step is in DAYS (Google Sheets behavior)
|
|
8645
|
-
const d = new Date(start);
|
|
8646
|
-
d.setDate(start.getDate() + index * step);
|
|
8647
|
-
row.push(d);
|
|
8648
|
-
} else {
|
|
8649
|
-
// Number sequence
|
|
8650
8494
|
row.push(start + index * step);
|
|
8651
|
-
}
|
|
8652
8495
|
}
|
|
8653
8496
|
|
|
8654
8497
|
result.push(row);
|
|
@@ -8854,16 +8697,7 @@ const NETWORKDAYS_INTL = NETWORKDAYS.INTL;
|
|
|
8854
8697
|
*/
|
|
8855
8698
|
function NOW() {
|
|
8856
8699
|
const d = new Date();
|
|
8857
|
-
const
|
|
8858
|
-
|
|
8859
|
-
const day = pad(d.getDate());
|
|
8860
|
-
const month = pad(d.getMonth() + 1);
|
|
8861
|
-
const year = d.getFullYear();
|
|
8862
|
-
|
|
8863
|
-
const hours = pad(d.getHours());
|
|
8864
|
-
const minutes = pad(d.getMinutes());
|
|
8865
|
-
const seconds = pad(d.getSeconds());
|
|
8866
|
-
|
|
8700
|
+
const { day, month, year, hours, minutes, seconds } = datePartition(d);
|
|
8867
8701
|
return returnSerial ? dateToSerial(d) : `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`
|
|
8868
8702
|
}
|
|
8869
8703
|
|
|
@@ -9231,11 +9065,9 @@ function YEARFRAC(start_date, end_date, basis) {
|
|
|
9231
9065
|
}
|
|
9232
9066
|
|
|
9233
9067
|
|
|
9234
|
-
// const start = new Date(2025, 0, 1); // Jan 1 2025
|
|
9235
|
-
// const end = new Date(2025, 11, 31); // Dec 31 2025
|
|
9236
9068
|
|
|
9237
|
-
// const
|
|
9238
|
-
// console.log(
|
|
9069
|
+
// const r = SEQUENCE(2, 1, DATE(2025,1,1),1);
|
|
9070
|
+
// console.log(r);
|
|
9239
9071
|
|
|
9240
9072
|
function isValidBinaryNumber(number) {
|
|
9241
9073
|
return /^[01]{1,10}$/.test(number)
|
package/package.json
CHANGED
package/types/cjs/index.d.cts
CHANGED
|
@@ -1057,7 +1057,7 @@ declare function DATEDIF(start_date: any, end_date: any, unit: any): number | Er
|
|
|
1057
1057
|
* @param {*} date_text Text that represents a date in an Excel date format, or a reference to a value that contains text that represents a date in an Excel date format.
|
|
1058
1058
|
* @returns
|
|
1059
1059
|
*/
|
|
1060
|
-
declare function DATEVALUE(date_text: any): number | Error
|
|
1060
|
+
declare function DATEVALUE(date_text: any): number | Error;
|
|
1061
1061
|
/**
|
|
1062
1062
|
* Returns the average of selected database entries.
|
|
1063
1063
|
*
|
|
@@ -1426,7 +1426,7 @@ declare function EOA(...args: any[]): Promise<any>;
|
|
|
1426
1426
|
* @returns
|
|
1427
1427
|
*/
|
|
1428
1428
|
declare function EOMONTH(start_date: any, months: any): number | Error | Date;
|
|
1429
|
-
declare function EPOCHTODATE(timestamp: any, timeUnit?: number):
|
|
1429
|
+
declare function EPOCHTODATE(timestamp: any, timeUnit?: number): string | Error;
|
|
1430
1430
|
/**
|
|
1431
1431
|
* Returns the error function.
|
|
1432
1432
|
*
|
|
@@ -3761,7 +3761,7 @@ declare function SECH(number: any): number | Error;
|
|
|
3761
3761
|
* @returns
|
|
3762
3762
|
*/
|
|
3763
3763
|
declare function SECOND(serial_number: any): any;
|
|
3764
|
-
declare function SEQUENCE(rows: any, columns?: number, start?: number, step?: number):
|
|
3764
|
+
declare function SEQUENCE(rows: any, columns?: number, start?: number, step?: number): number[][];
|
|
3765
3765
|
/**
|
|
3766
3766
|
* Returns the sum of a power series based on the formula.
|
|
3767
3767
|
*
|
package/types/esm/index.d.mts
CHANGED
|
@@ -996,7 +996,7 @@ export function DATEDIF(start_date: any, end_date: any, unit: any): number | Err
|
|
|
996
996
|
* @param {*} date_text Text that represents a date in an Excel date format, or a reference to a value that contains text that represents a date in an Excel date format.
|
|
997
997
|
* @returns
|
|
998
998
|
*/
|
|
999
|
-
export function DATEVALUE(date_text: any): number | Error
|
|
999
|
+
export function DATEVALUE(date_text: any): number | Error;
|
|
1000
1000
|
/**
|
|
1001
1001
|
* Returns the average of selected database entries.
|
|
1002
1002
|
*
|
|
@@ -1365,7 +1365,7 @@ export function EOA(...args: any[]): Promise<any>;
|
|
|
1365
1365
|
* @returns
|
|
1366
1366
|
*/
|
|
1367
1367
|
export function EOMONTH(start_date: any, months: any): number | Error | Date;
|
|
1368
|
-
export function EPOCHTODATE(timestamp: any, timeUnit?: number):
|
|
1368
|
+
export function EPOCHTODATE(timestamp: any, timeUnit?: number): string | Error;
|
|
1369
1369
|
/**
|
|
1370
1370
|
* Returns the error function.
|
|
1371
1371
|
*
|
|
@@ -3700,7 +3700,7 @@ export function SECH(number: any): number | Error;
|
|
|
3700
3700
|
* @returns
|
|
3701
3701
|
*/
|
|
3702
3702
|
export function SECOND(serial_number: any): any;
|
|
3703
|
-
export function SEQUENCE(rows: any, columns?: number, start?: number, step?: number):
|
|
3703
|
+
export function SEQUENCE(rows: any, columns?: number, start?: number, step?: number): number[][];
|
|
3704
3704
|
/**
|
|
3705
3705
|
* Returns the sum of a power series based on the formula.
|
|
3706
3706
|
*
|