import compareAsc from '../compareAsc/index' ; import differenceInMonths from '../differenceInMonths/index' ; import differenceInSeconds from '../differenceInSeconds/index' ; import defaultLocale from '../locale/en-US/index' ; import toDate from '../toDate/index' ; import cloneObject from '../_lib/cloneObject/index' ; import assign from '../_lib/assign' ; import getTimezoneOffsetInMilliseconds from '../_lib/getTimezoneOffsetInMilliseconds/index' ; import requiredArgs from '../_lib/requiredArgs/index' ; import type { LocaleOptions } from '../types' ; const MINUTES_IN_DAY = 1440 ; const MINUTES_IN_ALMOST_TWO_DAYS = 2520 ; const MINUTES_IN_MONTH = 43200 ; const MINUTES_IN_TWO_MONTHS = 86400 ; name category summary description param { Date | Number } date param { Date | Number } baseDate param options param { Boolean } options . includeSeconds param { Boolean } options . addSuffix param { Locale } options . locale - the locale object. See [Locale] https returns { String } throws throws throws throws example example example example export default function formatDistance ( dirtyDate , dirtyBaseDate , options = { } ) { requiredArgs ( 2 , arguments ) ; const locale = options . locale || defaultLocale ; if ( ! locale . formatDistance ) { throw new RangeError ( 'locale must contain 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 seconds = differenceInSeconds ( dateRight , dateLeft ) ; const offsetInSeconds = ( getTimezoneOffsetInMilliseconds ( dateRight ) - getTimezoneOffsetInMilliseconds ( dateLeft ) ) / 1000 ; const minutes = Math . round ( ( seconds - offsetInSeconds ) / 60 ) ; let months ; if ( minutes < 2 ) { if ( options . includeSeconds ) { if ( seconds < 5 ) { return locale . formatDistance ( 'lessThanXSeconds' , 5 , localizeOptions ) ; } else if ( seconds < 10 ) { return locale . formatDistance ( 'lessThanXSeconds' , 10 , localizeOptions ) ; } else if ( seconds < 20 ) { return locale . formatDistance ( 'lessThanXSeconds' , 20 , localizeOptions ) ; } else if ( seconds < 40 ) { return locale . formatDistance ( 'halfAMinute' , 0 , localizeOptions ) ; } else if ( seconds < 60 ) { return locale . formatDistance ( 'lessThanXMinutes' , 1 , localizeOptions ) ; } else { return locale . formatDistance ( 'xMinutes' , 1 , localizeOptions ) ; } } else { if ( minutes === 0 ) { return locale . formatDistance ( 'lessThanXMinutes' , 1 , localizeOptions ) ; } else { return locale . formatDistance ( 'xMinutes' , minutes , localizeOptions ) ; } } } else if ( minutes < 45 ) { return locale . formatDistance ( 'xMinutes' , minutes , localizeOptions ) ; } else if ( minutes < 90 ) { return locale . formatDistance ( 'aboutXHours' , 1 , localizeOptions ) ; } else if ( minutes < MINUTES_IN_DAY ) { const hours = Math . round ( minutes / 60 ) ; return locale . formatDistance ( 'aboutXHours' , hours , localizeOptions ) ; } else if ( minutes < MINUTES_IN_ALMOST_TWO_DAYS ) { return locale . formatDistance ( 'xDays' , 1 , localizeOptions ) ; } else if ( minutes < MINUTES_IN_MONTH ) { const days = Math . round ( minutes / MINUTES_IN_DAY ) ; return locale . formatDistance ( 'xDays' , days , localizeOptions ) ; } else if ( minutes < MINUTES_IN_TWO_MONTHS ) { months = Math . round ( minutes / MINUTES_IN_MONTH ) ; return locale . formatDistance ( 'aboutXMonths' , months , localizeOptions ) ; } months = differenceInMonths ( dateRight , dateLeft ) ; if ( months < 12 ) { const nearestMonth = Math . round ( minutes / MINUTES_IN_MONTH ) ; return locale . formatDistance ( 'xMonths' , nearestMonth , localizeOptions ) ; } else { const monthsSinceStartOfYear = months % 12 ; const years = Math . floor ( months / 12 ) ; if ( monthsSinceStartOfYear < 3 ) { return locale . formatDistance ( 'aboutXYears' , years , localizeOptions ) ; } else if ( monthsSinceStartOfYear < 9 ) { return locale . formatDistance ( 'overXYears' , years , localizeOptions ) ; } else { return locale . formatDistance ( 'almostXYears' , years + 1 , localizeOptions ) ; } } }