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