getPeriod.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import moment from 'moment';
  2. import {DEFAULT_STATS_PERIOD} from 'app/constants';
  3. import {getUtcDateString} from 'app/utils/dates';
  4. type DateObject = {
  5. /**
  6. * Relative period string in format "<int><unit>" (e.g. 4d for 4 days)
  7. */
  8. period?: string;
  9. /**
  10. * Starting date object
  11. */
  12. start?: string | Date | null;
  13. /**
  14. * Ending date object
  15. */
  16. end?: string | Date | null;
  17. };
  18. type Options = {
  19. /**
  20. * Doubles the given period (useful for getting previous period data)
  21. */
  22. shouldDoublePeriod?: boolean;
  23. };
  24. /**
  25. * Gets the period to query with if we need to double the initial period in order
  26. * to get data for the previous period
  27. *
  28. * Returns an object with either a period or start/end dates ({statsPeriod: string} or {start: string, end: string})
  29. */
  30. export const getPeriod = (
  31. {period, start, end}: DateObject,
  32. {shouldDoublePeriod}: Options = {}
  33. ) => {
  34. if (!period && !start && !end) {
  35. period = DEFAULT_STATS_PERIOD;
  36. }
  37. // you can not specify both relative and absolute periods
  38. // relative period takes precedence
  39. if (period) {
  40. if (!shouldDoublePeriod) {
  41. return {statsPeriod: period};
  42. }
  43. const [, periodNumber, periodLength] = period.match(/([0-9]+)([mhdw])/)!;
  44. return {statsPeriod: `${parseInt(periodNumber, 10) * 2}${periodLength}`};
  45. }
  46. if (!start || !end) {
  47. throw new Error('start and end required');
  48. }
  49. const formattedStart = getUtcDateString(start);
  50. const formattedEnd = getUtcDateString(end);
  51. if (shouldDoublePeriod) {
  52. // get duration of end - start and double
  53. const diff = moment(end).diff(moment(start));
  54. const previousPeriodStart = moment(start).subtract(diff);
  55. // This is not as accurate as having 2 start/end objs
  56. return {
  57. start: getUtcDateString(previousPeriodStart),
  58. end: formattedEnd,
  59. };
  60. }
  61. return {
  62. start: formattedStart,
  63. end: formattedEnd,
  64. };
  65. };