@discomedia/utils 1.0.20 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -282,7 +282,7 @@ class MarketCalendar {
282
282
  const yearHolidays = marketHolidays[year];
283
283
  if (!yearHolidays)
284
284
  return false;
285
- return Object.values(yearHolidays).some(holiday => holiday.date === formattedDate);
285
+ return Object.values(yearHolidays).some((holiday) => holiday.date === formattedDate);
286
286
  }
287
287
  /**
288
288
  * Checks if a date is an early close day in NY time.
@@ -398,7 +398,7 @@ function getMarketTimes(date) {
398
398
  * @param intradayReporting - 'market_hours', 'extended_hours', or 'continuous'
399
399
  * @returns true if within hours, false otherwise
400
400
  */
401
- function isWithinMarketHoursImpl(date, intradayReporting = 'market_hours') {
401
+ function isWithinMarketHours(date, intradayReporting = 'market_hours') {
402
402
  const calendar = new MarketCalendar();
403
403
  if (!calendar.isMarketDay(date))
404
404
  return false;
@@ -441,7 +441,9 @@ function getLastFullTradingDateImpl(currentDate = new Date()) {
441
441
  marketCloseMinutes = MARKET_CONFIG.TIMES.EARLY_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.EARLY_CLOSE.minute;
442
442
  }
443
443
  // If not a market day, or before open, or during market hours, return previous market day's close
444
- if (!calendar.isMarketDay(currentDate) || minutes < marketOpenMinutes || (minutes >= marketOpenMinutes && minutes < marketCloseMinutes)) {
444
+ if (!calendar.isMarketDay(currentDate) ||
445
+ minutes < marketOpenMinutes ||
446
+ (minutes >= marketOpenMinutes && minutes < marketCloseMinutes)) {
445
447
  const prevMarketDay = calendar.getPreviousMarketDay(currentDate);
446
448
  let prevCloseMinutes = MARKET_CONFIG.TIMES.MARKET_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.MARKET_CLOSE.minute;
447
449
  if (calendar.isEarlyCloseDay(prevMarketDay)) {
@@ -557,7 +559,7 @@ function calculatePeriodStartDate(endDate, period) {
557
559
  * @returns PeriodDates object
558
560
  */
559
561
  function getMarketTimePeriod(params) {
560
- const { period, end = new Date(), intraday_reporting = 'market_hours', outputFormat = 'iso', } = params;
562
+ const { period, end = new Date(), intraday_reporting = 'market_hours', outputFormat = 'iso' } = params;
561
563
  if (!period)
562
564
  throw new Error('Period is required');
563
565
  const calendar = new MarketCalendar();
@@ -620,7 +622,8 @@ function getMarketStatusImpl(date = new Date()) {
620
622
  let extendedEndMinutes = MARKET_CONFIG.TIMES.EXTENDED_END.hour * 60 + MARKET_CONFIG.TIMES.EXTENDED_END.minute;
621
623
  if (isEarlyCloseDay) {
622
624
  marketCloseMinutes = MARKET_CONFIG.TIMES.EARLY_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.EARLY_CLOSE.minute;
623
- extendedEndMinutes = MARKET_CONFIG.TIMES.EARLY_EXTENDED_END.hour * 60 + MARKET_CONFIG.TIMES.EARLY_EXTENDED_END.minute;
625
+ extendedEndMinutes =
626
+ MARKET_CONFIG.TIMES.EARLY_EXTENDED_END.hour * 60 + MARKET_CONFIG.TIMES.EARLY_EXTENDED_END.minute;
624
627
  }
625
628
  let status;
626
629
  let nextStatus;
@@ -716,15 +719,36 @@ function getLastFullTradingDate(currentDate = new Date()) {
716
719
  */
717
720
  function getNextMarketDay({ referenceDate } = {}) {
718
721
  const calendar = new MarketCalendar();
719
- const startDate = referenceDate || new Date();
722
+ const startDate = referenceDate ?? new Date();
723
+ // Find the next trading day (UTC Date object)
720
724
  const nextDate = calendar.getNextMarketDay(startDate);
721
- const yyyymmdd = `${nextDate.getUTCFullYear()}-${String(nextDate.getUTCMonth() + 1).padStart(2, '0')}-${String(nextDate.getUTCDate()).padStart(2, '0')}`;
725
+ // Convert to NY time before extracting Y-M-D parts
726
+ const nyNext = toNYTime(nextDate);
727
+ const yyyymmdd = `${nyNext.getUTCFullYear()}-${String(nyNext.getUTCMonth() + 1).padStart(2, '0')}-${String(nyNext.getUTCDate()).padStart(2, '0')}`;
722
728
  return {
723
- date: nextDate,
724
- yyyymmdd,
729
+ date: nextDate, // raw Date, unchanged
730
+ yyyymmdd, // correct trading date string
725
731
  dateISOString: nextDate.toISOString(),
726
732
  };
727
733
  }
734
+ /**
735
+ * Returns the previous market day before the reference date.
736
+ * @param referenceDate - Date object (default: now)
737
+ * @returns Object with date, yyyymmdd string, and ISO string
738
+ */
739
+ function getPreviousMarketDay({ referenceDate } = {}) {
740
+ const calendar = new MarketCalendar();
741
+ const startDate = referenceDate || new Date();
742
+ const prevDate = calendar.getPreviousMarketDay(startDate);
743
+ // convert to NY time first
744
+ const nyPrev = toNYTime(prevDate); // ← already in this file
745
+ const yyyymmdd = `${nyPrev.getUTCFullYear()}-${String(nyPrev.getUTCMonth() + 1).padStart(2, '0')}-${String(nyPrev.getUTCDate()).padStart(2, '0')}`;
746
+ return {
747
+ date: prevDate,
748
+ yyyymmdd,
749
+ dateISOString: prevDate.toISOString(),
750
+ };
751
+ }
728
752
  /**
729
753
  * Returns the trading date for a given time. Note: Just trims the date string; does not validate if the date is a market day.
730
754
  * @param time - a string, number (unix timestamp), or Date object representing the time
@@ -759,13 +783,13 @@ function getMarketStatus(options = {}) {
759
783
  return getMarketStatusImpl(date);
760
784
  }
761
785
  /**
762
- * Checks if a date/time is within market hours, extended hours, or continuous.
786
+ * Checks if a date is a market day.
763
787
  * @param date - Date object
764
- * @param intradayReporting - 'market_hours', 'extended_hours', or 'continuous'
765
- * @returns true if within hours, false otherwise
788
+ * @returns true if market day, false otherwise
766
789
  */
767
- function isWithinMarketHours(date, intradayReporting = 'market_hours') {
768
- return isWithinMarketHoursImpl(date, intradayReporting);
790
+ function isMarketDay(date) {
791
+ const calendar = new MarketCalendar();
792
+ return calendar.isMarketDay(date);
769
793
  }
770
794
  /**
771
795
  * Returns full trading days from market open to market close.
@@ -786,7 +810,9 @@ function getTradingStartAndEndDates(options = {}) {
786
810
  const marketOpenMinutes = MARKET_CONFIG.TIMES.MARKET_OPEN.hour * 60 + MARKET_CONFIG.TIMES.MARKET_OPEN.minute;
787
811
  const marketCloseMinutes = MARKET_CONFIG.TIMES.MARKET_CLOSE.hour * 60 + MARKET_CONFIG.TIMES.MARKET_CLOSE.minute;
788
812
  const minutes = nyEnd.getUTCHours() * 60 + nyEnd.getUTCMinutes();
789
- if (!calendar.isMarketDay(endDate) || minutes < marketOpenMinutes || (minutes >= marketOpenMinutes && minutes < marketCloseMinutes)) {
813
+ if (!calendar.isMarketDay(endDate) ||
814
+ minutes < marketOpenMinutes ||
815
+ (minutes >= marketOpenMinutes && minutes < marketCloseMinutes)) {
790
816
  // Before market open, not a market day, or during market hours: use previous market day
791
817
  endMarketDay = calendar.getPreviousMarketDay(endDate);
792
818
  }
@@ -879,7 +905,7 @@ function countTradingDays(startDate, endDate = new Date()) {
879
905
  return {
880
906
  days: Math.round(days * 1000) / 1000, // Round to 3 decimal places
881
907
  hours: Math.round(hours * 100) / 100, // Round to 2 decimal places
882
- minutes: Math.round(minutes)
908
+ minutes: Math.round(minutes),
883
909
  };
884
910
  }
885
911
  // Export MARKET_TIMES for compatibility
@@ -887,27 +913,27 @@ const MARKET_TIMES = {
887
913
  TIMEZONE: MARKET_CONFIG.TIMEZONE,
888
914
  PRE: {
889
915
  START: { HOUR: 4, MINUTE: 0, MINUTES: 240 },
890
- END: { HOUR: 9, MINUTE: 30, MINUTES: 570 }
916
+ END: { HOUR: 9, MINUTE: 30, MINUTES: 570 },
891
917
  },
892
918
  EARLY_MORNING: {
893
919
  START: { HOUR: 9, MINUTE: 30, MINUTES: 570 },
894
- END: { HOUR: 10, MINUTE: 0, MINUTES: 600 }
920
+ END: { HOUR: 10, MINUTE: 0, MINUTES: 600 },
895
921
  },
896
922
  EARLY_CLOSE_BEFORE_HOLIDAY: {
897
923
  START: { HOUR: 9, MINUTE: 30, MINUTES: 570 },
898
- END: { HOUR: 13, MINUTE: 0, MINUTES: 780 }
924
+ END: { HOUR: 13, MINUTE: 0, MINUTES: 780 },
899
925
  },
900
926
  EARLY_EXTENDED_BEFORE_HOLIDAY: {
901
927
  START: { HOUR: 13, MINUTE: 0, MINUTES: 780 },
902
- END: { HOUR: 17, MINUTE: 0, MINUTES: 1020 }
928
+ END: { HOUR: 17, MINUTE: 0, MINUTES: 1020 },
903
929
  },
904
930
  REGULAR: {
905
931
  START: { HOUR: 9, MINUTE: 30, MINUTES: 570 },
906
- END: { HOUR: 16, MINUTE: 0, MINUTES: 960 }
932
+ END: { HOUR: 16, MINUTE: 0, MINUTES: 960 },
907
933
  },
908
934
  EXTENDED: {
909
935
  START: { HOUR: 4, MINUTE: 0, MINUTES: 240 },
910
- END: { HOUR: 20, MINUTE: 0, MINUTES: 1200 }
936
+ END: { HOUR: 20, MINUTE: 0, MINUTES: 1200 },
911
937
  },
912
938
  };
913
939
 
@@ -18270,10 +18296,14 @@ const disco = {
18270
18296
  getMarketOpenClose: getMarketOpenClose,
18271
18297
  getLastFullTradingDate: getLastFullTradingDate,
18272
18298
  getNextMarketDay: getNextMarketDay,
18299
+ getPreviousMarketDay: getPreviousMarketDay,
18300
+ getMarketTimePeriod: getMarketTimePeriod,
18273
18301
  getMarketStatus: getMarketStatus,
18274
18302
  getNYTimeZone: getNYTimeZone,
18275
18303
  getTradingDate: getTradingDate,
18276
18304
  getTradingStartAndEndDates: getTradingStartAndEndDates,
18305
+ isMarketDay: isMarketDay,
18306
+ isWithinMarketHours: isWithinMarketHours,
18277
18307
  countTradingDays: countTradingDays,
18278
18308
  MARKET_TIMES: MARKET_TIMES,
18279
18309
  },