date-fns#differenceInCalendarMonths JavaScript Examples

The following examples show how to use date-fns#differenceInCalendarMonths. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: date.js    From umami with MIT License 6 votes vote down vote up
export function getDateRangeValues(startDate, endDate) {
  let unit = 'year';
  if (differenceInHours(endDate, startDate) <= 48) {
    unit = 'hour';
  } else if (differenceInCalendarDays(endDate, startDate) <= 90) {
    unit = 'day';
  } else if (differenceInCalendarMonths(endDate, startDate) <= 24) {
    unit = 'month';
  }

  return { startDate: startOfDay(startDate), endDate: endOfDay(endDate), unit };
}
Example #2
Source File: date.js    From umami with MIT License 5 votes vote down vote up
dateFuncs = {
  minute: [differenceInMinutes, addMinutes, startOfMinute],
  hour: [differenceInHours, addHours, startOfHour],
  day: [differenceInCalendarDays, addDays, startOfDay],
  month: [differenceInCalendarMonths, addMonths, startOfMonth],
  year: [differenceInCalendarYears, addYears, startOfYear],
}
Example #3
Source File: useGrid.js    From react-nice-dates with MIT License 4 votes vote down vote up
export default function useGrid({ locale, month: currentMonth, onMonthChange, transitionDuration, touchDragEnabled }) {
  const timeoutRef = useRef()
  const containerElementRef = useRef()
  const initialDragPositionRef = useRef(0)
  const [state, dispatch] = useReducer(reducer, createInitialState(currentMonth, locale))
  const { startDate, endDate, cellHeight, lastCurrentMonth, offset, origin, transition, isWide } = state

  useLayoutEffect(() => {
    const notDragging = !initialDragPositionRef.current

    if (!isSameMonth(lastCurrentMonth, currentMonth) && notDragging) {
      const containerElement = containerElementRef.current
      containerElement.classList.add('-transition')
      clearTimeout(timeoutRef.current)

      if (Math.abs(differenceInCalendarMonths(currentMonth, lastCurrentMonth)) <= 3) {
        dispatch({ type: 'transitionToCurrentMonth', currentMonth })

        timeoutRef.current = setTimeout(() => {
          dispatch({ type: 'reset', currentMonth })
        }, transitionDuration)
      } else {
        dispatch({ type: 'reset', currentMonth })
      }
    }
  }, [currentMonth]) // eslint-disable-line react-hooks/exhaustive-deps

  useLayoutEffect(() => {
    if (!touchDragEnabled) {
      return
    }

    const containerElement = containerElementRef.current
    const gridHeight = cellHeight * 6
    const halfGridHeight = gridHeight / 2

    if (containerElement) {
      const handleDragStart = event => {
        clearTimeout(timeoutRef.current)
        const computedOffset = Number(window.getComputedStyle(containerElement).transform.match(/([-+]?[\d.]+)/g)[5])
        let currentMonthPosition = 0

        if (!initialDragPositionRef.current) {
          const newStartDate = getStartDate(subMonths(currentMonth, 1), locale)
          currentMonthPosition = (rowsBetweenDates(newStartDate, currentMonth, locale) - 1) * cellHeight
          dispatch({ type: 'setRange', startDate: newStartDate, endDate: getEndDate(addMonths(currentMonth, 1), locale) })
        }

        containerElement.style.transform = `translate3d(0, ${computedOffset || -currentMonthPosition}px, 0)`
        containerElement.classList.remove('-transition')
        containerElement.classList.add('-moving')
        initialDragPositionRef.current = event.touches[0].clientY + (-computedOffset || currentMonthPosition)
      }

      const handleDrag = event => {
        const initialDragPosition = initialDragPositionRef.current
        const dragOffset = event.touches[0].clientY - initialDragPosition
        const previousMonth = subMonths(currentMonth, 1)
        const previousMonthPosition = (rowsBetweenDates(startDate, previousMonth, locale) - 1) * cellHeight
        const currentMonthPosition = (rowsBetweenDates(startDate, currentMonth, locale) - 1) * cellHeight
        const nextMonth = addMonths(currentMonth, 1)
        const nextMonthPosition = (rowsBetweenDates(startDate, nextMonth, locale) - 1) * cellHeight

        if (dragOffset < 0) {
          if (Math.abs(dragOffset) > currentMonthPosition && isBefore(endDate, addMonths(currentMonth, 2))) {
            dispatch({ type: 'setEndDate', value: getEndDate(nextMonth, locale) })
          }
        } else if (dragOffset > 0) {
          const newStartDate = getStartDate(previousMonth, locale)
          const newCurrentMonthPosition = (rowsBetweenDates(newStartDate, currentMonth, locale) - 1) * cellHeight
          initialDragPositionRef.current += newCurrentMonthPosition
          dispatch({ type: 'setStartDate', value: newStartDate })
        }

        const shouldChangeToNextMonth = Math.abs(dragOffset) > nextMonthPosition - halfGridHeight
        const shouldChangeToPreviousMonth =
          Math.abs(dragOffset) > previousMonthPosition - halfGridHeight &&
          Math.abs(dragOffset) < currentMonthPosition - halfGridHeight

        if (shouldChangeToNextMonth) {
          onMonthChange(nextMonth)
        } else if (shouldChangeToPreviousMonth) {
          onMonthChange(previousMonth)
        }

        containerElement.style.transform = `translate3d(0, ${dragOffset}px, 0)`
        event.preventDefault()
      }

      const handleDragEnd = event => {
        const currentMonthPosition = (rowsBetweenDates(startDate, currentMonth, locale) - 1) * cellHeight
        containerElement.style.transform = `translate3d(0, ${-currentMonthPosition}px, 0)`
        containerElement.classList.add('-transition')
        containerElement.classList.remove('-moving')

        timeoutRef.current = setTimeout(() => {
          initialDragPositionRef.current = 0
          containerElement.style.transform = 'translate3d(0, 0, 0)'
          containerElement.classList.remove('-transition')
          dispatch({ type: 'reset', currentMonth: currentMonth })
        }, transitionDuration)

        if (Math.abs(initialDragPositionRef.current - currentMonthPosition - event.changedTouches[0].clientY) > 10) {
          event.preventDefault()
          event.stopPropagation()
        }
      }

      containerElement.addEventListener('touchstart', handleDragStart)
      containerElement.addEventListener('touchmove', handleDrag)
      containerElement.addEventListener('touchend', handleDragEnd)

      return () => {
        containerElement.removeEventListener('touchstart', handleDragStart)
        containerElement.removeEventListener('touchmove', handleDrag)
        containerElement.removeEventListener('touchend', handleDragEnd)
      }
    }
  })

  useEffect(() => {
    const handleResize = () => {
      const containerElement = containerElementRef.current
      const containerWidth = containerElement.offsetWidth
      const cellWidth = containerWidth / 7
      let newCellHeight = 1
      let wide = false

      if (cellWidth > 60) {
        newCellHeight += Math.round(cellWidth * 0.75)
        wide = true
      } else {
        newCellHeight += Math.round(cellWidth)
      }

      dispatch({ type: 'setIsWide', value: wide })
      dispatch({ type: 'setCellHeight', value: newCellHeight })
    }

    window.addEventListener('resize', handleResize)
    handleResize()

    return () => {
      window.removeEventListener('resize', handleResize)
    }
  }, [])

  return {
    startDate,
    endDate,
    cellHeight,
    containerElementRef,
    offset,
    origin,
    transition,
    isWide
  }
}