@fileverse-dev/formulajs 4.4.32 → 4.4.34
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 +86 -4
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +264 -3
- package/lib/esm/index.mjs +263 -4
- package/package.json +2 -2
- package/types/cjs/index.d.cts +5 -3
- package/types/esm/index.d.mts +4 -2
package/lib/cjs/index.cjs
CHANGED
|
@@ -8129,6 +8129,11 @@ function DATE(year, month, day) {
|
|
|
8129
8129
|
if (result.getFullYear() < 0) {
|
|
8130
8130
|
result = num;
|
|
8131
8131
|
}
|
|
8132
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8133
|
+
const dayResult = pad(result.getDate());
|
|
8134
|
+
const monthResult = pad(result.getMonth() + 1);
|
|
8135
|
+
const yearResult = result.getFullYear();
|
|
8136
|
+
result = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8132
8137
|
}
|
|
8133
8138
|
|
|
8134
8139
|
return returnSerial ? dateToSerial(result) : result
|
|
@@ -8389,7 +8394,15 @@ function EDATE(start_date, months) {
|
|
|
8389
8394
|
|
|
8390
8395
|
start_date.setDate(storedDay);
|
|
8391
8396
|
|
|
8392
|
-
|
|
8397
|
+
|
|
8398
|
+
let widthoutSerial = start_date;
|
|
8399
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8400
|
+
const dayResult = pad(widthoutSerial.getDate());
|
|
8401
|
+
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8402
|
+
const yearResult = widthoutSerial.getFullYear();
|
|
8403
|
+
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8404
|
+
|
|
8405
|
+
return returnSerial ? dateToSerial(start_date) : widthoutSerial
|
|
8393
8406
|
}
|
|
8394
8407
|
|
|
8395
8408
|
/**
|
|
@@ -8416,9 +8429,237 @@ function EOMONTH(start_date, months) {
|
|
|
8416
8429
|
|
|
8417
8430
|
const eoMonth = new Date(start_date.getFullYear(), start_date.getMonth() + months + 1, 0);
|
|
8418
8431
|
|
|
8419
|
-
|
|
8432
|
+
|
|
8433
|
+
let widthoutSerial = eoMonth;
|
|
8434
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8435
|
+
const dayResult = pad(widthoutSerial.getDate());
|
|
8436
|
+
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8437
|
+
const yearResult = widthoutSerial.getFullYear();
|
|
8438
|
+
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8439
|
+
|
|
8440
|
+
return returnSerial ? dateToSerial(eoMonth) : widthoutSerial
|
|
8441
|
+
}
|
|
8442
|
+
|
|
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
|
+
function EPOCHTODATE(timestamp, timeUnit = 1) {
|
|
8606
|
+
let ms;
|
|
8607
|
+
|
|
8608
|
+
switch (timeUnit) {
|
|
8609
|
+
case 1: // seconds → milliseconds
|
|
8610
|
+
ms = timestamp * 1000;
|
|
8611
|
+
break;
|
|
8612
|
+
|
|
8613
|
+
case 2: // milliseconds
|
|
8614
|
+
ms = timestamp;
|
|
8615
|
+
break;
|
|
8616
|
+
|
|
8617
|
+
case 3: // microseconds → milliseconds
|
|
8618
|
+
ms = timestamp / 1000;
|
|
8619
|
+
break;
|
|
8620
|
+
|
|
8621
|
+
default:
|
|
8622
|
+
throw new Error("Invalid time_unit. Use 1 (sec), 2 (ms), or 3 (µs).");
|
|
8623
|
+
}
|
|
8624
|
+
|
|
8625
|
+
return new Date(ms); // JS Date is always internally UTC
|
|
8626
|
+
}
|
|
8627
|
+
|
|
8628
|
+
function SEQUENCE(rows, columns = 1, start = 1, step = 1) {
|
|
8629
|
+
const result = [];
|
|
8630
|
+
|
|
8631
|
+
const isDate = start instanceof Date;
|
|
8632
|
+
|
|
8633
|
+
// Normalize date (remove time)
|
|
8634
|
+
const normalizeDate = (d) =>
|
|
8635
|
+
new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8636
|
+
|
|
8637
|
+
if (isDate) start = normalizeDate(start);
|
|
8638
|
+
|
|
8639
|
+
for (let r = 0; r < rows; r++) {
|
|
8640
|
+
const row = [];
|
|
8641
|
+
|
|
8642
|
+
for (let c = 0; c < columns; c++) {
|
|
8643
|
+
const index = r * columns + c; // linear index (0-based)
|
|
8644
|
+
|
|
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
|
+
row.push(start + index * step);
|
|
8653
|
+
}
|
|
8654
|
+
}
|
|
8655
|
+
|
|
8656
|
+
result.push(row);
|
|
8657
|
+
}
|
|
8658
|
+
|
|
8659
|
+
return result;
|
|
8420
8660
|
}
|
|
8421
8661
|
|
|
8662
|
+
|
|
8422
8663
|
/**
|
|
8423
8664
|
* Converts a serial number to an hour.
|
|
8424
8665
|
*
|
|
@@ -8614,7 +8855,18 @@ const NETWORKDAYS_INTL = NETWORKDAYS.INTL;
|
|
|
8614
8855
|
* @returns
|
|
8615
8856
|
*/
|
|
8616
8857
|
function NOW() {
|
|
8617
|
-
|
|
8858
|
+
const d = new Date();
|
|
8859
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
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
|
+
|
|
8869
|
+
return returnSerial ? dateToSerial(d) : `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`
|
|
8618
8870
|
}
|
|
8619
8871
|
|
|
8620
8872
|
/**
|
|
@@ -8980,6 +9232,13 @@ function YEARFRAC(start_date, end_date, basis) {
|
|
|
8980
9232
|
}
|
|
8981
9233
|
}
|
|
8982
9234
|
|
|
9235
|
+
|
|
9236
|
+
// const start = new Date(2025, 0, 1); // Jan 1 2025
|
|
9237
|
+
// const end = new Date(2025, 11, 31); // Dec 31 2025
|
|
9238
|
+
|
|
9239
|
+
// const days = networkDaysIntl(start, end, 7);
|
|
9240
|
+
// console.log(days);
|
|
9241
|
+
|
|
8983
9242
|
function isValidBinaryNumber(number) {
|
|
8984
9243
|
return /^[01]{1,10}$/.test(number)
|
|
8985
9244
|
}
|
|
@@ -29969,6 +30228,7 @@ exports.EDATE = EDATE;
|
|
|
29969
30228
|
exports.EFFECT = EFFECT;
|
|
29970
30229
|
exports.EOA = EOA;
|
|
29971
30230
|
exports.EOMONTH = EOMONTH;
|
|
30231
|
+
exports.EPOCHTODATE = EPOCHTODATE;
|
|
29972
30232
|
exports.ERF = ERF;
|
|
29973
30233
|
exports.ERFC = ERFC;
|
|
29974
30234
|
exports.ERFCPRECISE = ERFCPRECISE;
|
|
@@ -30188,6 +30448,7 @@ exports.SEARCH = SEARCH;
|
|
|
30188
30448
|
exports.SEC = SEC;
|
|
30189
30449
|
exports.SECH = SECH;
|
|
30190
30450
|
exports.SECOND = SECOND;
|
|
30451
|
+
exports.SEQUENCE = SEQUENCE;
|
|
30191
30452
|
exports.SERIESSUM = SERIESSUM;
|
|
30192
30453
|
exports.SIGN = SIGN;
|
|
30193
30454
|
exports.SIN = SIN;
|
package/lib/esm/index.mjs
CHANGED
|
@@ -8127,6 +8127,11 @@ function DATE(year, month, day) {
|
|
|
8127
8127
|
if (result.getFullYear() < 0) {
|
|
8128
8128
|
result = num;
|
|
8129
8129
|
}
|
|
8130
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8131
|
+
const dayResult = pad(result.getDate());
|
|
8132
|
+
const monthResult = pad(result.getMonth() + 1);
|
|
8133
|
+
const yearResult = result.getFullYear();
|
|
8134
|
+
result = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8130
8135
|
}
|
|
8131
8136
|
|
|
8132
8137
|
return returnSerial ? dateToSerial(result) : result
|
|
@@ -8387,7 +8392,15 @@ function EDATE(start_date, months) {
|
|
|
8387
8392
|
|
|
8388
8393
|
start_date.setDate(storedDay);
|
|
8389
8394
|
|
|
8390
|
-
|
|
8395
|
+
|
|
8396
|
+
let widthoutSerial = start_date;
|
|
8397
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8398
|
+
const dayResult = pad(widthoutSerial.getDate());
|
|
8399
|
+
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8400
|
+
const yearResult = widthoutSerial.getFullYear();
|
|
8401
|
+
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8402
|
+
|
|
8403
|
+
return returnSerial ? dateToSerial(start_date) : widthoutSerial
|
|
8391
8404
|
}
|
|
8392
8405
|
|
|
8393
8406
|
/**
|
|
@@ -8414,9 +8427,237 @@ function EOMONTH(start_date, months) {
|
|
|
8414
8427
|
|
|
8415
8428
|
const eoMonth = new Date(start_date.getFullYear(), start_date.getMonth() + months + 1, 0);
|
|
8416
8429
|
|
|
8417
|
-
|
|
8430
|
+
|
|
8431
|
+
let widthoutSerial = eoMonth;
|
|
8432
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8433
|
+
const dayResult = pad(widthoutSerial.getDate());
|
|
8434
|
+
const monthResult = pad(widthoutSerial.getMonth() + 1);
|
|
8435
|
+
const yearResult = widthoutSerial.getFullYear();
|
|
8436
|
+
widthoutSerial = `${dayResult}/${monthResult}/${yearResult}`;
|
|
8437
|
+
|
|
8438
|
+
return returnSerial ? dateToSerial(eoMonth) : widthoutSerial
|
|
8439
|
+
}
|
|
8440
|
+
|
|
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
|
+
function EPOCHTODATE(timestamp, timeUnit = 1) {
|
|
8604
|
+
let ms;
|
|
8605
|
+
|
|
8606
|
+
switch (timeUnit) {
|
|
8607
|
+
case 1: // seconds → milliseconds
|
|
8608
|
+
ms = timestamp * 1000;
|
|
8609
|
+
break;
|
|
8610
|
+
|
|
8611
|
+
case 2: // milliseconds
|
|
8612
|
+
ms = timestamp;
|
|
8613
|
+
break;
|
|
8614
|
+
|
|
8615
|
+
case 3: // microseconds → milliseconds
|
|
8616
|
+
ms = timestamp / 1000;
|
|
8617
|
+
break;
|
|
8618
|
+
|
|
8619
|
+
default:
|
|
8620
|
+
throw new Error("Invalid time_unit. Use 1 (sec), 2 (ms), or 3 (µs).");
|
|
8621
|
+
}
|
|
8622
|
+
|
|
8623
|
+
return new Date(ms); // JS Date is always internally UTC
|
|
8624
|
+
}
|
|
8625
|
+
|
|
8626
|
+
function SEQUENCE(rows, columns = 1, start = 1, step = 1) {
|
|
8627
|
+
const result = [];
|
|
8628
|
+
|
|
8629
|
+
const isDate = start instanceof Date;
|
|
8630
|
+
|
|
8631
|
+
// Normalize date (remove time)
|
|
8632
|
+
const normalizeDate = (d) =>
|
|
8633
|
+
new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8634
|
+
|
|
8635
|
+
if (isDate) start = normalizeDate(start);
|
|
8636
|
+
|
|
8637
|
+
for (let r = 0; r < rows; r++) {
|
|
8638
|
+
const row = [];
|
|
8639
|
+
|
|
8640
|
+
for (let c = 0; c < columns; c++) {
|
|
8641
|
+
const index = r * columns + c; // linear index (0-based)
|
|
8642
|
+
|
|
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
|
+
row.push(start + index * step);
|
|
8651
|
+
}
|
|
8652
|
+
}
|
|
8653
|
+
|
|
8654
|
+
result.push(row);
|
|
8655
|
+
}
|
|
8656
|
+
|
|
8657
|
+
return result;
|
|
8418
8658
|
}
|
|
8419
8659
|
|
|
8660
|
+
|
|
8420
8661
|
/**
|
|
8421
8662
|
* Converts a serial number to an hour.
|
|
8422
8663
|
*
|
|
@@ -8612,7 +8853,18 @@ const NETWORKDAYS_INTL = NETWORKDAYS.INTL;
|
|
|
8612
8853
|
* @returns
|
|
8613
8854
|
*/
|
|
8614
8855
|
function NOW() {
|
|
8615
|
-
|
|
8856
|
+
const d = new Date();
|
|
8857
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
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
|
+
|
|
8867
|
+
return returnSerial ? dateToSerial(d) : `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`
|
|
8616
8868
|
}
|
|
8617
8869
|
|
|
8618
8870
|
/**
|
|
@@ -8978,6 +9230,13 @@ function YEARFRAC(start_date, end_date, basis) {
|
|
|
8978
9230
|
}
|
|
8979
9231
|
}
|
|
8980
9232
|
|
|
9233
|
+
|
|
9234
|
+
// const start = new Date(2025, 0, 1); // Jan 1 2025
|
|
9235
|
+
// const end = new Date(2025, 11, 31); // Dec 31 2025
|
|
9236
|
+
|
|
9237
|
+
// const days = networkDaysIntl(start, end, 7);
|
|
9238
|
+
// console.log(days);
|
|
9239
|
+
|
|
8981
9240
|
function isValidBinaryNumber(number) {
|
|
8982
9241
|
return /^[01]{1,10}$/.test(number)
|
|
8983
9242
|
}
|
|
@@ -29846,4 +30105,4 @@ function MYANIMELIST() {
|
|
|
29846
30105
|
|
|
29847
30106
|
const utils = { errors, symbols, date };
|
|
29848
30107
|
|
|
29849
|
-
export { AAVE, ABS, ACCRINT, ACOS, ACOSH, ACOT, ACOTH, AGGREGATE, AND, ARABIC, ARTEMIS, ASIN, ASINH, ATAN, ATAN2, ATANH, AVEDEV, AVERAGE, AVERAGEA, AVERAGEIF, AVERAGEIFS, BASE, BESSELI, BESSELJ, BESSELK, BESSELY, BETA, BETADIST, BETAINV, BIN2DEC, BIN2HEX, BIN2OCT, BINOM, BINOMDIST, BITAND, BITLSHIFT, BITOR, BITRSHIFT, BITXOR, BLOCKSCOUT, CEILING, CEILINGMATH, CEILINGPRECISE, CHAR, CHIDIST, CHIDISTRT, CHIINV, CHIINVRT, CHISQ, CHITEST, CHOOSE, CIRCLES, CLEAN, CODE, COINGECKO, COLUMN, COLUMNS, COMBIN, COMBINA, COMPLEX, CONCAT, CONCATENATE, CONFIDENCE, CONVERT, CORREL, COS, COSH, COT, COTH, COUNT, COUNTA, COUNTBLANK, COUNTIF, COUNTIFS, COUPDAYS, COVAR, COVARIANCE, COVARIANCEP, COVARIANCES, CRITBINOM, CSC, CSCH, CUMIPMT, CUMPRINC, DATE, DATEDIF, DATEVALUE, DAVERAGE, DAY, DAYS, DAYS360, DB, DCOUNT, DCOUNTA, DDB, DEC2BIN, DEC2HEX, DEC2OCT, DECIMAL, DEFILLAMA, DEGREES, DELTA, DEVSQ, DGET, DISC, DMAX, DMIN, DOLLAR, DOLLARDE, DOLLARFR, DPRODUCT, DSTDEV, DSTDEVP, DSUM, DUNE, DVAR, DVARP, EDATE, EFFECT, EOA, EOMONTH, ERF, ERFC, ERFCPRECISE, ERFPRECISE, ERROR, ETHERSCAN, EVEN, EXACT, EXP, EXPON, EXPONDIST, F, FACT, FACTDOUBLE, FALSE, FARCASTER, FDIST, FDISTRT, FIND, FINV, FINVRT, FIREFLY, FISHER, FISHERINV, FIXED, FLOOR, FLOORMATH, FLOORPRECISE, FLVURL, FORECAST, FREQUENCY, FTEST, FV, FVSCHEDULE, GAMMA, GAMMADIST, GAMMAINV, GAMMALN, GAMMALNPRECISE, GAUSS, GCD, GEOMEAN, GESTEP, GNOSIS, GROWTH, HARMEAN, HEX2BIN, HEX2DEC, HEX2OCT, HLOOKUP, HOUR, HYPGEOM, HYPGEOMDIST, IF, IFERROR, IFNA, IFS, IMABS, IMAGINARY, IMARGUMENT, IMCONJUGATE, IMCOS, IMCOSH, IMCOT, IMCSC, IMCSCH, IMDIV, IMEXP, IMLN, IMLOG10, IMLOG2, IMPOWER, IMPRODUCT, IMREAL, IMSEC, IMSECH, IMSIN, IMSINH, IMSQRT, IMSUB, IMSUM, IMTAN, INDEX, INT, INTERCEPT, IPMT, IRR, ISBLANK, ISDATE, ISERR, ISERROR, ISEVEN, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISO, ISODD, ISOWEEKNUM, ISPMT, ISTEXT, KURT, LARGE, LCM, LEFT, LEN, LENS, LINEST, LN, LOG, LOG10, LOGEST, LOGINV, LOGNORM, LOGNORMDIST, LOGNORMINV, LOOKUP, LOWER, MATCH, MAX, MAXA, MAXIFS, MEDIAN, MEERKAT, MID, MIN, MINA, MINIFS, MINUS$1 as MINUS, MINUTE, MIRR, MMULT, MOD, MODE, MODEMULT, MODESNGL, MONTH, MROUND, MULTINOMIAL, MUNIT, MYANIMELIST, N, NA, NEGBINOM, NEGBINOMDIST, NETWORKDAYS, NETWORKDAYSINTL, NETWORKDAYS_INTL, NEYNAR, NOMINAL, NORM, NORMDIST, NORMINV, NORMSDIST, NORMSINV, NOT, NOW, NPER, NPV, NUMBERVALUE, OCT2BIN, OCT2DEC, OCT2HEX, ODD, OR, PDURATION, PEARSON, PERCENTILE, PERCENTILEEXC, PERCENTILEINC, PERCENTRANK, PERCENTRANKEXC, PERCENTRANKINC, PERMUT, PERMUTATIONA, PHI, PI, PMT, PNL, POISSON, POISSONDIST, POLYMARKET, POWER, PPMT, PRICE, PRICEDISC, PRIVACYPOOL, PROB, PRODUCT, PROPER, PV, QUARTILE, QUARTILEEXC, QUARTILEINC, QUOTIENT, RADIANS, RAND, RANDBETWEEN, RANK, RANKAVG, RANKEQ, RATE, REPLACE, REPT, RIGHT, ROMAN, ROTKI, ROUND, ROUNDDOWN, ROUNDUP, ROW, ROWS, RRI, RSQ, SAFE, SEARCH, SEC, SECH, SECOND, SERIESSUM, SIGN, SIN, SINH, SKEW, SKEWP, SLN, SLOPE, SMALL, SMARTCONTRACT, SORT, SQRT, SQRTPI, STANDARDIZE, STDEV, STDEVA, STDEVP, STDEVPA, STDEVS, STEYX, SUBSTITUTE, SUBTOTAL, SUM, SUMIF, SUMIFS, SUMPRODUCT, SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2, SWITCH, SYD, T, TALLY, TAN, TANH, TBILLEQ, TBILLPRICE, TBILLYIELD, TDIST, TDISTRT, TEXT, TEXTJOIN, TIME, TIMEVALUE, TINV, TODAY, TRANSPOSE, TREND, TRIM, TRIMMEAN, TRUE, TRUNC, TTEST, TYPE, UNICHAR, UNICODE, UNIQUE, UNISWAP, UPPER, VALUE, VAR, VARA, VARP, VARPA, VARS, VLOOKUP, WALLET, WEEKDAY, WEEKNUM, WEIBULL, WEIBULLDIST, WORKDAY, WORKDAYINTL, WORKDAY_INTL, XIRR, XLOOKUP, XNPV, XOR, YEAR, YEARFRAC, YIELD, Z, ZTEST, utils };
|
|
30108
|
+
export { AAVE, ABS, ACCRINT, ACOS, ACOSH, ACOT, ACOTH, AGGREGATE, AND, ARABIC, ARTEMIS, ASIN, ASINH, ATAN, ATAN2, ATANH, AVEDEV, AVERAGE, AVERAGEA, AVERAGEIF, AVERAGEIFS, BASE, BESSELI, BESSELJ, BESSELK, BESSELY, BETA, BETADIST, BETAINV, BIN2DEC, BIN2HEX, BIN2OCT, BINOM, BINOMDIST, BITAND, BITLSHIFT, BITOR, BITRSHIFT, BITXOR, BLOCKSCOUT, CEILING, CEILINGMATH, CEILINGPRECISE, CHAR, CHIDIST, CHIDISTRT, CHIINV, CHIINVRT, CHISQ, CHITEST, CHOOSE, CIRCLES, CLEAN, CODE, COINGECKO, COLUMN, COLUMNS, COMBIN, COMBINA, COMPLEX, CONCAT, CONCATENATE, CONFIDENCE, CONVERT, CORREL, COS, COSH, COT, COTH, COUNT, COUNTA, COUNTBLANK, COUNTIF, COUNTIFS, COUPDAYS, COVAR, COVARIANCE, COVARIANCEP, COVARIANCES, CRITBINOM, CSC, CSCH, CUMIPMT, CUMPRINC, DATE, DATEDIF, DATEVALUE, DAVERAGE, DAY, DAYS, DAYS360, DB, DCOUNT, DCOUNTA, DDB, DEC2BIN, DEC2HEX, DEC2OCT, DECIMAL, DEFILLAMA, DEGREES, DELTA, DEVSQ, DGET, DISC, DMAX, DMIN, DOLLAR, DOLLARDE, DOLLARFR, DPRODUCT, DSTDEV, DSTDEVP, DSUM, DUNE, DVAR, DVARP, EDATE, EFFECT, EOA, EOMONTH, EPOCHTODATE, ERF, ERFC, ERFCPRECISE, ERFPRECISE, ERROR, ETHERSCAN, EVEN, EXACT, EXP, EXPON, EXPONDIST, F, FACT, FACTDOUBLE, FALSE, FARCASTER, FDIST, FDISTRT, FIND, FINV, FINVRT, FIREFLY, FISHER, FISHERINV, FIXED, FLOOR, FLOORMATH, FLOORPRECISE, FLVURL, FORECAST, FREQUENCY, FTEST, FV, FVSCHEDULE, GAMMA, GAMMADIST, GAMMAINV, GAMMALN, GAMMALNPRECISE, GAUSS, GCD, GEOMEAN, GESTEP, GNOSIS, GROWTH, HARMEAN, HEX2BIN, HEX2DEC, HEX2OCT, HLOOKUP, HOUR, HYPGEOM, HYPGEOMDIST, IF, IFERROR, IFNA, IFS, IMABS, IMAGINARY, IMARGUMENT, IMCONJUGATE, IMCOS, IMCOSH, IMCOT, IMCSC, IMCSCH, IMDIV, IMEXP, IMLN, IMLOG10, IMLOG2, IMPOWER, IMPRODUCT, IMREAL, IMSEC, IMSECH, IMSIN, IMSINH, IMSQRT, IMSUB, IMSUM, IMTAN, INDEX, INT, INTERCEPT, IPMT, IRR, ISBLANK, ISDATE, ISERR, ISERROR, ISEVEN, ISLOGICAL, ISNA, ISNONTEXT, ISNUMBER, ISO, ISODD, ISOWEEKNUM, ISPMT, ISTEXT, KURT, LARGE, LCM, LEFT, LEN, LENS, LINEST, LN, LOG, LOG10, LOGEST, LOGINV, LOGNORM, LOGNORMDIST, LOGNORMINV, LOOKUP, LOWER, MATCH, MAX, MAXA, MAXIFS, MEDIAN, MEERKAT, MID, MIN, MINA, MINIFS, MINUS$1 as MINUS, MINUTE, MIRR, MMULT, MOD, MODE, MODEMULT, MODESNGL, MONTH, MROUND, MULTINOMIAL, MUNIT, MYANIMELIST, N, NA, NEGBINOM, NEGBINOMDIST, NETWORKDAYS, NETWORKDAYSINTL, NETWORKDAYS_INTL, NEYNAR, NOMINAL, NORM, NORMDIST, NORMINV, NORMSDIST, NORMSINV, NOT, NOW, NPER, NPV, NUMBERVALUE, OCT2BIN, OCT2DEC, OCT2HEX, ODD, OR, PDURATION, PEARSON, PERCENTILE, PERCENTILEEXC, PERCENTILEINC, PERCENTRANK, PERCENTRANKEXC, PERCENTRANKINC, PERMUT, PERMUTATIONA, PHI, PI, PMT, PNL, POISSON, POISSONDIST, POLYMARKET, POWER, PPMT, PRICE, PRICEDISC, PRIVACYPOOL, PROB, PRODUCT, PROPER, PV, QUARTILE, QUARTILEEXC, QUARTILEINC, QUOTIENT, RADIANS, RAND, RANDBETWEEN, RANK, RANKAVG, RANKEQ, RATE, REPLACE, REPT, RIGHT, ROMAN, ROTKI, ROUND, ROUNDDOWN, ROUNDUP, ROW, ROWS, RRI, RSQ, SAFE, SEARCH, SEC, SECH, SECOND, SEQUENCE, SERIESSUM, SIGN, SIN, SINH, SKEW, SKEWP, SLN, SLOPE, SMALL, SMARTCONTRACT, SORT, SQRT, SQRTPI, STANDARDIZE, STDEV, STDEVA, STDEVP, STDEVPA, STDEVS, STEYX, SUBSTITUTE, SUBTOTAL, SUM, SUMIF, SUMIFS, SUMPRODUCT, SUMSQ, SUMX2MY2, SUMX2PY2, SUMXMY2, SWITCH, SYD, T, TALLY, TAN, TANH, TBILLEQ, TBILLPRICE, TBILLYIELD, TDIST, TDISTRT, TEXT, TEXTJOIN, TIME, TIMEVALUE, TINV, TODAY, TRANSPOSE, TREND, TRIM, TRIMMEAN, TRUE, TRUNC, TTEST, TYPE, UNICHAR, UNICODE, UNIQUE, UNISWAP, UPPER, VALUE, VAR, VARA, VARP, VARPA, VARS, VLOOKUP, WALLET, WEEKDAY, WEEKNUM, WEIBULL, WEIBULLDIST, WORKDAY, WORKDAYINTL, WORKDAY_INTL, XIRR, XLOOKUP, XNPV, XOR, YEAR, YEARFRAC, YIELD, Z, ZTEST, utils };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fileverse-dev/formulajs",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.34",
|
|
4
4
|
"description": "JavaScript implementation of most Microsoft Excel formula functions",
|
|
5
5
|
"author": "Formulajs",
|
|
6
6
|
"publishConfig": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
],
|
|
46
46
|
"scripts": {
|
|
47
47
|
"build:crypto-constants": "esbuild src/crypto-constants.js --bundle --outfile=lib/esm/crypto-constants.mjs --format=esm",
|
|
48
|
-
"build": "rollup -c &&
|
|
48
|
+
"build": "rollup -c && npm run types && npm run build:crypto-constants",
|
|
49
49
|
"format": "npm run prettier:fix && npm run lint:fix",
|
|
50
50
|
"lint": "eslint .",
|
|
51
51
|
"lint:fix": "eslint --fix .",
|