import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index' ; import compareAsc from '../compareAsc/index' ; import toDate from '../toDate/index' ; import cloneObject from '../_lib/cloneObject/index' ; import assign from '../_lib/assign/index' ; import defaultLocale from '../locale/en-US/index' ; import requiredArgs from '../_lib/requiredArgs/index' ; import type { LocaleOptions , Unit } from '../types' ; const MILLISECONDS_IN_MINUTE = 1000 * 60 ; const MINUTES_IN_DAY = 60 * 24 ; const MINUTES_IN_MONTH = MINUTES_IN_DAY * 30 ; const MINUTES_IN_YEAR = MINUTES_IN_DAY * 365 ; name category summary description param { Date | Number } date param { Date | Number } baseDate param options param { Boolean } options . addSuffix param { 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year' } options . unit param { 'floor' | 'ceil' | 'round' } options . roundingMethod param { Locale } options . locale - the locale object. See [Locale] https returns { String } throws throws throws throws throws throws example example example example example example export default function formatDistanceStrict ( dirtyDate , dirtyBaseDate , options = { } ) { requiredArgs ( 2 , arguments ) ; const locale = options . locale || defaultLocale ; if ( ! locale . formatDistance ) { throw new RangeError ( 'locale must contain localize.formatDistance property' ) ; } const comparison = compareAsc ( dirtyDate , dirtyBaseDate ) ; if ( isNaN ( comparison ) ) { throw new RangeError ( 'Invalid time value' ) ; } const localizeOptions = assign ( cloneObject ( options ) , { addSuffix : Boolean ( options . addSuffix ) , comparison : comparison as - 1 | 0 | 1 , } ) ; let dateLeft ; let dateRight ; if ( comparison > 0 ) { dateLeft = toDate ( dirtyBaseDate ) ; dateRight = toDate ( dirtyDate ) ; } else { dateLeft = toDate ( dirtyDate ) ; dateRight = toDate ( dirtyBaseDate ) ; } const roundingMethod = options . roundingMethod == null ? 'round' : String ( options . roundingMethod ) ; let roundingMethodFn ; if ( roundingMethod === 'floor' ) { roundingMethodFn = Math . floor ; } else if ( roundingMethod === 'ceil' ) { roundingMethodFn = Math . ceil ; } else if ( roundingMethod === 'round' ) { roundingMethodFn = Math . round ; } else { throw new RangeError ( "roundingMethod must be 'floor', 'ceil' or 'round'" ) ; } const milliseconds = dateRight . getTime ( ) - dateLeft . getTime ( ) ; const minutes = milliseconds / MILLISECONDS_IN_MINUTE ; const timezoneOffset = getTimezoneOffsetInMilliseconds ( dateRight ) - getTimezoneOffsetInMilliseconds ( dateLeft ) ; const dstNormalizedMinutes = ( milliseconds - timezoneOffset ) / MILLISECONDS_IN_MINUTE ; let unit ; if ( options . unit == null ) { if ( minutes < 1 ) { unit = 'second' ; } else if ( minutes < 60 ) { unit = 'minute' ; } else if ( minutes < MINUTES_IN_DAY ) { unit = 'hour' ; } else if ( dstNormalizedMinutes < MINUTES_IN_MONTH ) { unit = 'day' ; } else if ( dstNormalizedMinutes < MINUTES_IN_YEAR ) { unit = 'month' ; } else { unit = 'year' ; } } else { unit = String ( options . unit ) ; } if ( unit === 'second' ) { const seconds = roundingMethodFn ( milliseconds / 1000 ) ; return locale . formatDistance ( 'xSeconds' , seconds , localizeOptions ) ; } else if ( unit === 'minute' ) { const roundedMinutes = roundingMethodFn ( minutes ) ; return locale . formatDistance ( 'xMinutes' , roundedMinutes , localizeOptions ) ; } else if ( unit === 'hour' ) { const hours = roundingMethodFn ( minutes / 60 ) ; return locale . formatDistance ( 'xHours' , hours , localizeOptions ) ; } else if ( unit === 'day' ) { const days = roundingMethodFn ( dstNormalizedMinutes / MINUTES_IN_DAY ) ; return locale . formatDistance ( 'xDays' , days , localizeOptions ) ; } else if ( unit === 'month' ) { const months = roundingMethodFn ( dstNormalizedMinutes / MINUTES_IN_MONTH ) ; return months === 12 && options . unit !== 'month' ? locale . formatDistance ( 'xYears' , 1 , localizeOptions ) : locale . formatDistance ( 'xMonths' , months , localizeOptions ) ; } else if ( unit === 'year' ) { const years = roundingMethodFn ( dstNormalizedMinutes / MINUTES_IN_YEAR ) ; return locale . formatDistance ( 'xYears' , years , localizeOptions ) ; } throw new RangeError ( "unit must be 'second', 'minute', 'hour', 'day', 'month' or 'year'" ) ; }