function _roundDateTime(direction, dateTime, unit, precision) {
  const units = {
    hour: {
      maxValue: 24
    },
    minute: {
      maxValue: 60
    },
    second: {
      maxValue: 60
    },
    millisecond: {
      maxValue: 1e3
    }
  };
  let maxValue = Number.MAX_SAFE_INTEGER;
  let value = 0;
  let rounded = false;
  let subRatio = 1;
  Object.keys(units).forEach((k) => {
    if (k === unit) {
      value = dateTime.get(k);
      maxValue = units[k].maxValue;
      rounded = true;
    } else if (rounded) {
      subRatio *= units[k].maxValue;
      value += dateTime.get(k) / subRatio;
      dateTime = dateTime.set({ [k]: 0 });
    }
  });
  value = Math[direction](value / precision) * precision;
  value = Math.min(value, maxValue);
  dateTime = dateTime.set({ [unit]: value });
  return dateTime;
}
const ceilDateTime = (dateTime, unit, precision) => _roundDateTime("ceil", dateTime, unit, precision);
const floorDateTime = (dateTime, unit, precision) => _roundDateTime("floor", dateTime, unit, precision);
const durationRegex = /(-?\d*\.?\d+(?:e[-+]?\d+)?)\s*([a-zμ]*)/i;
const UNIT_MULTIPLIERS = {
  milliseconds: 1,
  millisecond: 1,
  second: 1e3,
  seconds: 1e3,
  minute: 60 * 1e3,
  minutes: 60 * 1e3,
  hour: 60 * 60 * 1e3,
  hours: 60 * 60 * 1e3,
  day: 24 * 60 * 60 * 1e3,
  days: 24 * 60 * 60 * 1e3
};
function parseDuration(str) {
  const match = durationRegex.exec(str);
  if (!match) {
    return;
  }
  const value = parseFloat(match[1]);
  const unit = match[2].toLowerCase().replace(/s$/, "");
  if (unit in UNIT_MULTIPLIERS) {
    return {
      [unit]: value
    };
  }
}

export { ceilDateTime, floorDateTime, parseDuration };
