import { isInt } from '../util/misc' ; export type DurationInput = DurationObjectInput | string | number ; export interface DurationObjectInput { years ? : number ; year ? : number ; months ? : number ; month ? : number ; weeks ? : number ; week ? : number ; days ? : number ; day ? : number ; hours ? : number ; hour ? : number ; minutes ? : number ; minute ? : number ; seconds ? : number ; second ? : number ; milliseconds ? : number ; millisecond ? : number ; ms ? : number ; } export interface Duration { years : number ; months : number ; days : number ; milliseconds : number ; specifiedWeeks ? : boolean ; } const INTERNAL_UNITS = [ 'years' , 'months' , 'days' , 'milliseconds' ] ; const PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/ ; export function createDuration ( input , unit ? ) { if ( typeof input === 'string' ) { return parseString ( input ) ; } if ( typeof input === 'object' && input ) { return parseObject ( input ) ; } if ( typeof input === 'number' ) { return parseObject ( { [ unit || 'milliseconds' ] : input } ) ; } return null ; } function parseString ( s ) { let m = PARSE_RE . exec ( s ) ; if ( m ) { let sign = m [ 1 ] ? - 1 : 1 ; return { years : 0 , months : 0 , days : sign * ( m [ 2 ] ? parseInt ( m [ 2 ] , 10 ) : 0 ) , milliseconds : sign * ( ( m [ 3 ] ? parseInt ( m [ 3 ] , 10 ) : 0 ) * 60 * 60 * 1000 + ( m [ 4 ] ? parseInt ( m [ 4 ] , 10 ) : 0 ) * 60 * 1000 + ( m [ 5 ] ? parseInt ( m [ 5 ] , 10 ) : 0 ) * 1000 + ( m [ 6 ] ? parseInt ( m [ 6 ] , 10 ) : 0 ) ) , } ; } return null ; } function parseObject ( obj ) { let duration = { years : obj . years || obj . year || 0 , months : obj . months || obj . month || 0 , days : obj . days || obj . day || 0 , milliseconds : ( obj . hours || obj . hour || 0 ) * 60 * 60 * 1000 + ( obj . minutes || obj . minute || 0 ) * 60 * 1000 + ( obj . seconds || obj . second || 0 ) * 1000 + ( obj . milliseconds || obj . millisecond || obj . ms || 0 ) , } ; let weeks = obj . weeks || obj . week ; if ( weeks ) { duration . days += weeks * 7 ; duration . specifiedWeeks = true ; } return duration ; } export function durationsEqual ( d0 , d1 ) { return d0 . years === d1 . years && d0 . months === d1 . months && d0 . days === d1 . days && d0 . milliseconds === d1 . milliseconds ; } export function asCleanDays ( dur ) { if ( ! dur . years && ! dur . months && ! dur . milliseconds ) { return dur . days ; } return 0 ; } export function addDurations ( d0 , d1 ) { return { years : d0 . years + d1 . years , months : d0 . months + d1 . months , days : d0 . days + d1 . days , milliseconds : d0 . milliseconds + d1 . milliseconds , } ; } export function subtractDurations ( d1 , d0 ) { return { years : d1 . years - d0 . years , months : d1 . months - d0 . months , days : d1 . days - d0 . days , milliseconds : d1 . milliseconds - d0 . milliseconds , } ; } export function multiplyDuration ( d , n ) { return { years : d . years * n , months : d . months * n , days : d . days * n , milliseconds : d . milliseconds * n , } ; } export function asRoughYears ( dur ) { return asRoughDays ( dur ) / 365 ; } export function asRoughMonths ( dur ) { return asRoughDays ( dur ) / 30 ; } export function asRoughDays ( dur ) { return asRoughMs ( dur ) / 864e5 ; } export function asRoughHours ( dur ) { return asRoughMs ( dur ) / ( 1000 * 60 * 60 ) ; } export function asRoughMinutes ( dur ) { return asRoughMs ( dur ) / ( 1000 * 60 ) ; } export function asRoughSeconds ( dur ) { return asRoughMs ( dur ) / 1000 ; } export function asRoughMs ( dur ) { return dur . years * ( 365 * 864e5 ) + dur . months * ( 30 * 864e5 ) + dur . days * 864e5 + dur . milliseconds ; } export function wholeDivideDurations ( numerator , denominator ) { let res = null ; for ( let i = 0 ; i < INTERNAL_UNITS . length ; i += 1 ) { let unit = INTERNAL_UNITS [ i ] ; if ( denominator [ unit ] ) { let localRes = numerator [ unit ] / denominator [ unit ] ; if ( ! isInt ( localRes ) || ( res !== null && res !== localRes ) ) { return null ; } res = localRes ; } else if ( numerator [ unit ] ) { return null ; } } return res ; } export function greatestDurationDenominator ( dur ) { let ms = dur . milliseconds ; if ( ms ) { if ( ms % 1000 !== 0 ) { return { unit : 'millisecond' , value : ms } ; } if ( ms % ( 1000 * 60 ) !== 0 ) { return { unit : 'second' , value : ms / 1000 } ; } if ( ms % ( 1000 * 60 * 60 ) !== 0 ) { return { unit : 'minute' , value : ms / ( 1000 * 60 ) } ; } if ( ms ) { return { unit : 'hour' , value : ms / ( 1000 * 60 * 60 ) } ; } } if ( dur . days ) { if ( dur . specifiedWeeks && dur . days % 7 === 0 ) { return { unit : 'week' , value : dur . days / 7 } ; } return { unit : 'day' , value : dur . days } ; } if ( dur . months ) { return { unit : 'month' , value : dur . months } ; } if ( dur . years ) { return { unit : 'year' , value : dur . years } ; } return { unit : 'millisecond' , value : 0 } ; }