import { identity , get , pickBy } from 'lodash' ; import { Decimal } from 'decimal.js' ; import Strings from './strings' ; export type Duration = { days : number ; hours : number ; minutes : number ; seconds : number ; milliseconds : number ; } ; export default class Durations { protected locale : string ; protected strings : Strings ; constructor ( locale = 'en-US' ) { this . locale = locale ; this . strings = new Strings ( this . locale ) ; } param milliseconds public format ( milliseconds ) { if ( ! milliseconds ) { return this . localize ( 0 , 'milliseconds' ) ; } const object = pickBy ( this . toObject ( milliseconds ) , identity ) ; const entries = Object . entries ( object ) ; if ( entries . length > 2 ) { delete object . milliseconds ; } else if ( object . seconds > 0 && object . milliseconds > 0 ) { object . seconds = parseFloat ( new Decimal ( object . seconds + ( object . milliseconds / 1000 ) ) . toDecimalPlaces ( 3 ) . valueOf ( ) ) ; delete object . milliseconds ; } return Object . entries ( object ) . map ( entry => { return this . localize ( entry [ 1 ] , entry [ 0 ] ) ; } ) . join ( ' ' ) ; } param milliseconds protected toObject ( milliseconds ) { let seconds = Math . floor ( milliseconds / 1000 ) ; milliseconds = milliseconds % 1000 ; let minutes = Math . floor ( seconds / 60 ) ; seconds = seconds % 60 ; let hours = Math . floor ( minutes / 60 ) ; minutes = minutes % 60 ; const days = Math . floor ( hours / 24 ) ; hours = hours % 24 ; return { days , hours , minutes , seconds , milliseconds } ; } param amount param unit protected localize ( amount , unit ) { return get ( { days : this . strings . plural ( '1 day|:n days' , amount ) , hours : this . strings . plural ( '1 hour|:n hours' , amount ) , minutes : this . strings . plural ( '1 min|:n min' , amount ) , seconds : this . strings . set ( ':0s' , amount ) , milliseconds : this . strings . set ( ':0ms' , amount ) } , unit , '' ) ; } }