cheliyan
cheliyan

Reputation: 1787

How to convert time in milliseconds to hours, min, sec format in JavaScript?

I have a time as a number of milliseconds and I want to convert it to a HH:MM:SS format. It should wrap around, with milliseconds = 86400000 I want to get 00:00:00.

Upvotes: 145

Views: 291372

Answers (30)

Emmanuel
Emmanuel

Reputation: 9

This converts milliseconds to 3 different human-readable values.

/**
 * Converts milliseconds to 3 different human-readable values
 * @param {{duration: number, includeSeconds: boolean, includeDays: boolean}} params
 * @returns {[string, string, string, {days: (number | string), hours: (number | string), minutes: (number | string), seconds: (number | string), milliseconds: number}]} An array with 4 values, the first 3 being human
 * readable values, the last being the value of each time duration.
 */
function msToTime({
  duration,
  includeSeconds = true,
  includeDays = false
}) {
  let milliseconds = Math.floor((duration % 1000) / 100),
    seconds = Math.floor((duration / 1000) % 60),
    minutes = Math.floor((duration / (1000 * 60)) % 60),
    hours = Math.floor((duration / (1000 * 60 * 60)) % 24),
    days = Math.floor(duration / (1000 * 60 * 60 * 24))

  days = days < 10 ? '0' + days : days
  hours = hours < 10 ? '0' + hours : hours
  minutes = minutes < 10 ? '0' + minutes : minutes
  seconds = seconds < 10 ? '0' + seconds : seconds

  return [
    // Returns padded time values, if days and seconds were set to be 
    // included, it'll appear in hierarchical order. E.g. "01:00:00:00.0", 
    // where '01' is the days value, and '00.0' is the seconds value.
    `${includeDays ? `${days}:` : ''}${hours}:${minutes}${
            includeSeconds ? `:${seconds}.${milliseconds}` : ''
        }`,
    
    // Returns trimmed time values, if days and seconds were set to be 
    // included, it'll appear in hierarchical order. E.g. "0:1:0:0", where 
    // the first '0' is the days value, and the last '0' is the seconds 
    // value.
    `${includeDays ? `${Number(days)}:` : ''}${Number(hours)}:${Number(
            minutes
        )}${includeSeconds ? `:${Number(seconds)}` : ''}`,
    
    // Returns human readable time in this format if days and seconds were 
    // set to be included: "8 days, 19 hours, 17 minutes, 10 seconds".
    `${
            includeDays && Number(days)
                ? `${Number(days)} day${
                        Number(days) > 1 || Number(days) === 0 ? 's' : ''
                  }${Number(hours) ? ', ' : ''}`
                : ''
        }${
            Number(hours)
                ? `${Number(hours)} hour${
                        Number(hours) > 1 || Number(hours) === 0 ? 's' : ''
                  }${Number(minutes) ? ', ' : ''}`
                : ''
        }${
            Number(minutes)
                ? `${Number(minutes)} minute${
                        Number(minutes) > 1 || Number(minutes) === 0 ? 's' : ''
                  }${includeSeconds && Number(seconds) ? ', ' : ''}`
                : ''
        }${
            includeSeconds && Number(seconds)
                ? `${Number(seconds)} second${
                        Number(seconds) > 1 || Number(seconds) === 0 ? 's' : ''
                  }`
                : ''
        }` || 'a moment',
    
    // Returns the padded values of each time unit.
    {
      days,
      hours,
      minutes,
      seconds,
      milliseconds
    },
  ]
}

console.log(
  msToTime({
    duration: 86400000,
    includeSeconds: true,
    includeDays: true
  })
)
console.log(
  msToTime({
    duration: 3600000,
    includeSeconds: true,
    includeDays: true
  })
)
console.log(
  msToTime({
    duration: 760630000,
    includeSeconds: true,
    includeDays: true
  })
)
console.log(
  msToTime({
    duration: 1000,
    includeSeconds: true,
    includeDays: true
  })
)
console.log(
  msToTime({
    duration: 100,
    includeSeconds: false,
    includeDays: false
  })
)

Upvotes: -1

Lee Goddard
Lee Goddard

Reputation: 11173

A Date object can be constructed from milliseconds:

const date = new Date(0, 0, 0, 0, 0, 0, milliseconds);

In your question you say milliseconds should 'wrap around' at 86400000. Since we know there are 86400000 milliseconds in a day, we can simply take the time from the date object, and ignore every other part of the date as irrelevant.

The time can then be obtained in any number of formats. The one you require matches that used in the United Kingdom, locale en-GB:

const hms = d.toLocaleTimeString('en-GB');

Upvotes: 3

marioosh
marioosh

Reputation: 28556

Complete period pipe i'm using in Angular app. It convert days, too.

import { Pipe, PipeTransform, Injectable } from '@angular/core';

@Pipe({
  name: 'period'
})
@Injectable({
  providedIn: 'root'
})
export class PeriodPipe implements PipeTransform {

  transform(value: any): any {
    return this.intervalFormat(value);
  }

  private intervalFormat(ms:number) {
    if(ms == 0 || typeof ms == 'undefined' || ms == null) {
        return '0ms';
    } else {    
      let ms1 = Math.abs(ms);
      let dd = Math.floor(ms1/1000/3600/24);
      if(dd > 0) {
        ms1 = ms1%(dd*24*3600*1000);
      }
      let sec = ms1/1000;
      let hh = Math.floor(sec/3600);
      let mm = Math.floor((sec%3600)/60);
      let ss = Math.floor((sec%3600)%60);
      let ms2 = Math.floor(ms1%1000);
      let ret = (dd!=0?(this.zeroPad(dd,1) + 'd '):'') + 
                (hh!=0?(this.zeroPad(hh,1) + 'h '):'') + 
                (mm!=0?(this.zeroPad(mm,2) + 'm '):'') + 
                (ss!=0?(this.zeroPad(ss,2) + 's '):'') + 
                (ms2!=0?(this.zeroPad(ms2,1) + 'ms '):'');
      return ret;
    }
  }

  private zeroPad(num:number, places:number) {
    let zero = places - num.toString().length + 1;
    return Array(+(zero > 0 && zero)).join("0") + num;
  }  
}

Upvotes: 0

Tom Auger
Tom Auger

Reputation: 20101

Based on the modulus approach of other answers, this is a modern, compact ES6 approach:

function splitMillis(millis){
    const days = Math.floor(millis / 86400000);
    const hours = Math.floor(millis / 3600000) % 24;
    const minutes = Math.floor(millis / 60000) % 60;
    const seconds = Math.floor(millis / 1000) % 60;
    const millisRemaining = millis % 1000;

    return { days, hours, minutes, seconds, millis : millisRemaining };
}

You can destructure the result to make your life easy.

const { days, hours, minutes, seconds, millis } = splitMillis(2824461)

You can also just destructure what you're interested in: const { minutes, seconds } = splitMillis(2824461)

This answer is better than some of the answers here because it doesn't require a full Timestamp. For example, if you want to know elapsed time or time differential as in splitMillis(new Date() - someOtherDate)

All that being said, I hope this answer becomes obsolete soon with Temporal: https://tc39.es/proposal-temporal/docs/cookbook.html

Upvotes: 2

Ariel Fatecha
Ariel Fatecha

Reputation: 9

Use UTCString...

let timeStr = new Date(millis).toUTCString().match("..:..:..")[0];
// timeStr = "20:30:22"

Upvotes: 0

Jake
Jake

Reputation: 1097

Human Readable output:

e.g. 21 Days, 14 Hrs, 18 Min, 18 Sec, 753 milliseconds.

Building off of @Nofi's awesome answer for human readable output, I made a more readable (in my opinion) and accurate version (and less complicated than @Steven Spungin's answer, albeit theirs is really cool) for my personal use and I figured I'd share it here.

function msToTime(ms) {
  let seconds = Math.floor((ms / 1000) % 60);
  let minutes = Math.floor((ms / (1000 * 60)) % 60);
  let hours = Math.floor((ms / (1000 * 60 * 60)) % 24);
  let days = Math.floor(ms / (1000 * 60 * 60 * 24));
  let time = '';
  if (days > 0) {
    time += days + " Days, ";
    ms -= days * (1000 * 60 * 60 * 24);
  }
  if (hours > 0) {
    time += hours + " Hrs, ";
    ms -= hours * (1000 * 60 * 60);
  }
  if (minutes > 0) {
    time += minutes + " Min, ";
    ms -= minutes * (1000 * 60);
  }
  if (seconds > 0) {
    time += seconds + " Sec, ";
    ms -= seconds * 1000;
  }
  return time += ms + " milliseconds.";
}
console.log('msToTime(1865898753): \n', msToTime(1865898753));
console.log('msToTime(123456789): \n', msToTime(123456789));
console.log('msToTime(85457): \n', msToTime(85457));
console.log('msToTime(547): \n', msToTime(547));

Upvotes: 1

Xx-Mohit-xX
Xx-Mohit-xX

Reputation: 1

If anyone still need here's a modified version of one of the code snippets posted above in js by https://stackoverflow.com/a/58826445/20067539

function timeConversion(duration) { 
    var portions = []; 
    var msInDay = 1000 * 60 * 60 * 24
    var days = Math.trunc(duration / msInDay);
    if (days > 0 ) {
        portions.push(days + (days === 1 ? " day" : " days"))
        duration = duration - (days * msInDay)
    }
    var msInHour = 1000 * 60 * 60; 
    var hours = Math.trunc(duration / msInHour);
    if (hours > 0) {
    portions.push(hours + (hours === 1 ? ' hour' : ' hours'));
    duration = duration - (hours * msInHour);
} 
var msInMinute = 1000 * 60; 
var minutes = Math.trunc(duration / msInMinute); 
if (minutes > 0) {
    portions.push(minutes + (minutes === 1 ? ' minute' : ' minutes'));
    duration = duration - (minutes * msInMinute);
}
var seconds = Math.trunc(duration / 1000); 
if (seconds > 0) {
    portions.push(seconds + (seconds === 1 ? ' second' : ' seconds'));
}
return portions.join(' ');
}
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000)));
console.log(timeConversion((60 * 60 * 1000)));
console.log(timeConversion((60 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((59 * 1000)));

Upvotes: -1

FelipeC
FelipeC

Reputation: 9488

I don't see the need for complication in all these answers, it's easy to add zeros by adding a power of 10:

function timeToString(t) {
  const value =
    ((t / 3600_000 % 24) | 0) * 10000 +
    ((t / 60_000 % 60) | 0) * 100 +
    ((t / 1_000 % 60) | 0);
  return (1000000 + value).toString().replace(/1(..)(..)(..)/, '$1:$2:$3');
}

Upvotes: -1

Leon Williams
Leon Williams

Reputation: 764

I recently ran into this situation. My focus was on clean readability and reusability.

Use

(See function definition below)

timeUnits(86400000) // {days: 1, hours: 0, minutes: 0, seconds: 0, ms: 0}

Then you can use the data to do whatever you want (like build a string).

Other examples:

timeUnits(214870123) // {days: 2, hours: 11, minutes: 41, seconds: 10, ms: 123}
timeUnits('70123') // null

Function

/**
 * Converts milliseconds into greater time units as possible
 * @param {int} ms - Amount of time measured in milliseconds
 * @return {?Object} Reallocated time units. NULL on failure.
 */
function timeUnits( ms ) {
    if ( !Number.isInteger(ms) ) {
        return null
    }
    /**
     * Takes as many whole units from the time pool (ms) as possible
     * @param {int} msUnit - Size of a single unit in milliseconds
     * @return {int} Number of units taken from the time pool
     */
    const allocate = msUnit => {
        const units = Math.trunc(ms / msUnit)
        ms -= units * msUnit
        return units
    }
    // Property order is important here.
    // These arguments are the respective units in ms.
    return {
        // weeks: allocate(604800000), // Uncomment for weeks
        days: allocate(86400000),
        hours: allocate(3600000),
        minutes: allocate(60000),
        seconds: allocate(1000),
        ms: ms // remainder
    }
}

It's written in such a way so that you can easily implement other units (for example, where I commented out implementation for weeks) so long as you know their worth in milliseconds.

Upvotes: 7

Heretic Sic
Heretic Sic

Reputation: 406

let dateTimeStr = new Date(1949778000);
dateTimeStr = Math.floor(dateTimeStr/86400000) +' days '+ dateTimeStr.getHours() +' hours '+ dateTimeStr.getMinutes() +' minutes '+ dateTimeStr.getSeconds() +' seconds';
console.log(dateTimeStr);

You don't have to calculate the days if you don't need them

"22 days 16 hours 36 minutes 18 seconds"

Upvotes: 0

Robert-Jan Kuyper
Robert-Jan Kuyper

Reputation: 3306

A refactor from @dusht to ES6+ and more functional:

const addPrefix = time => time < 10 ? '0' + time : time;
const toHours = time => addPrefix(Math.floor((time / (1000 * 60 * 60)) % 24));
const toMinutes = time => addPrefix(Math.floor((time / (1000 * 60)) % 60));
const toSeconds = (ime => addPrefix(Math.floor((time / 1000) % 60));
const toMiliseconds = time => Math.floor((time % 1000) / 100);


const milisecondToHoursAndMinute = time => {
  const hours = toHours(time);
  const minutes = toMinutes(time);
  const seconds = toSeconds(time);
  const miliseconds = toMiliseconds(time);

  return `${hours}:${minutes}:${seconds}.${miliseconds}`
}

Upvotes: 0

Sinjai
Sinjai

Reputation: 1277

Format as hh:mm:ss with optional padding

(1:59:59 or 01:59:59)
(1:59 or 01:59)
(Default: no padding)

Based loosely on Chand's answer.

function formatMilliseconds(milliseconds, padStart) {
    function pad(num) {
        return `${num}`.padStart(2, '0');
    }
    let asSeconds = milliseconds / 1000;

    let hours = undefined;
    let minutes = Math.floor(asSeconds / 60);
    let seconds = Math.floor(asSeconds % 60);

    if (minutes > 59) {
        hours = Math.floor(minutes / 60);
        minutes %= 60;
    }

    return hours
        ? `${padStart ? pad(hours) : hours}:${pad(minutes)}:${pad(seconds)}`
        : `${padStart ? pad(minutes) : minutes}:${pad(seconds)}`;
}

Tests:

let s = 1000;
let m = 60*s;
let h = 60*m;
console.log(formatMilliseconds(1*h));               // 1:00:00
console.log(formatMilliseconds(1*h, true));         // 01:00:00
console.log(formatMilliseconds(59*m + 59*s));       // 59:59
console.log(formatMilliseconds(59*m + 59*s, true)); // 59:59
console.log(formatMilliseconds(9*m + 9*s));         // 9:09
console.log(formatMilliseconds(9*m + 9*s, true));   // 09:09
console.log(formatMilliseconds(5*s));               // 0:05
console.log(formatMilliseconds(5*s, true));         // 00:05
console.log(formatMilliseconds(2400*s));            // 40:00
console.log(formatMilliseconds(2400*s, true));      // 40:00

.
.
.
If you need millisecond precision, you can get the fractional part using the following:

(asSeconds % 1).toFixed(3).substring(1)

Your returns would end up looking like this (break it up for readability as necessary):

`${padStart ? pad(hours) : hours}:${pad(minutes)}:${pad(seconds)}${(asSeconds % 1).toFixed(3).substring(1)}`

There are probably better ways to do that, but this naive solution gets the job done.

Test:

let asSeconds = 59.5219;
let seconds = Math.floor(asSeconds);
console.log(`${pad(seconds)}${(asSeconds % 1).toFixed(3).substring(1)}`);
// Equivalent to above, without using `pad()`:
//console.log(`${String(seconds).padStart(2, '0')}${(asSeconds % 1).toFixed(3).substring(1)}`);

// Output: 59.522

Upvotes: 6

Dushyant
Dushyant

Reputation: 4960

How about creating a function like this:

function msToTime(duration) {
  var milliseconds = Math.floor((duration % 1000) / 100),
    seconds = Math.floor((duration / 1000) % 60),
    minutes = Math.floor((duration / (1000 * 60)) % 60),
    hours = Math.floor((duration / (1000 * 60 * 60)) % 24);

  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? "0" + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;

  return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
}
console.log(msToTime(300000))

Upvotes: 209

Nofi
Nofi

Reputation: 2175

To Convert time in millisecond to human readable format.

function msToTime(ms) {
  let seconds = (ms / 1000).toFixed(1);
  let minutes = (ms / (1000 * 60)).toFixed(1);
  let hours = (ms / (1000 * 60 * 60)).toFixed(1);
  let days = (ms / (1000 * 60 * 60 * 24)).toFixed(1);
  if (seconds < 60) return seconds + " Sec";
  else if (minutes < 60) return minutes + " Min";
  else if (hours < 24) return hours + " Hrs";
  else return days + " Days"
}

console.log(msToTime(1000))
console.log(msToTime(10000))
console.log(msToTime(300000))
console.log(msToTime(3600000))
console.log(msToTime(86400000))

"Out Put Sample"

Upvotes: 92

Shady Smaoui
Shady Smaoui

Reputation: 1285

// The following is written in Typescript, should be easy to translate to JS

function humanReadableDuration(msDuration: int): string {
    const h = Math.floor(msDuration / 1000 / 60 / 60);
    const m = Math.floor((msDuration / 1000 / 60 / 60 - h) * 60);
    const s = Math.floor(((msDuration / 1000 / 60 / 60 - h) * 60 - m) * 60);

    // To get time format 00:00:00
    const seconds: string = s < 10 ? `0${s}` : `${s}`;
    const minutes: string = m < 10 ? `0${m}` : `${m}`;
    const hours: string = h < 10 ? `0${h}` : `${h}`;

    return `${hours}h ${minutes}m ${seconds}s`;
}

Upvotes: 4

Mustapha-Belkacim
Mustapha-Belkacim

Reputation: 1821

Extending on @Rick's answer, I prefer something like this:

function msToReadableTime(time){
  const second = 1000;
  const minute = second * 60;
  const hour = minute * 60;

  let hours = Math.floor(time / hour % 24);
  let minutes = Math.floor(time / minute % 60);
  let seconds = Math.floor(time / second % 60);
 

  return hours + ':' + minutes + ":" + seconds;
}

Upvotes: 3

Sneha Morye
Sneha Morye

Reputation: 7

I works for me as i get milliseconds=1592380675409 using javascript method getTime() which returns the number of milliseconds between midnight of January 1, 1970 and the specified date.

var d = new Date();//Wed Jun 17 2020 13:27:55 GMT+0530 (India Standard Time)
var n = d.getTime();//1592380675409 this value is store somewhere

//function call 
console.log(convertMillisecToHrMinSec(1592380675409));

var convertMillisecToHrMinSec = (time) => {
  let date = new Date(time);
  let hr = date.getHours();
  let min = date.getMinutes();
  let sec = date.getSeconds();

  hr = (hr < 10) ? "0"+ hr : hr;
  min = (min < 10) ? "0"+ min : min;
  sec = (sec < 10) ? "0"+ sec : sec;

  return hr + ':' + min + ":" + sec;//01:27:55
}

Upvotes: 0

Rick O&#39;Shea
Rick O&#39;Shea

Reputation: 1449

Human-readable code for human-readable output and you can extend this to light years or nanoseconds or what have you very intuitively. Obviously you'd want to convert this to a function and re-use some of those intermediate modulo calls.

second = 1000 
minute = second * 60
hour = minute * 60 
day = hour * 24

test = 3 * day + 2 * hour + 11 * minute + 58 * second

console.log(Math.floor(test / day))
console.log(Math.floor(test % day / hour))
console.log(Math.floor(test % day % hour / minute))
console.log(Math.floor(test % day % hour % minute / second))

Upvotes: 3

anonimito
anonimito

Reputation: 207

Sorry, late to the party. The accepted answer did not cut it for me, so I wrote it myself.

Output:

2h 59s
1h 59m
1h
1h 59s
59m 59s
59s

Code (Typescript):

function timeConversion(duration: number) {
  const portions: string[] = [];

  const msInHour = 1000 * 60 * 60;
  const hours = Math.trunc(duration / msInHour);
  if (hours > 0) {
    portions.push(hours + 'h');
    duration = duration - (hours * msInHour);
  }

  const msInMinute = 1000 * 60;
  const minutes = Math.trunc(duration / msInMinute);
  if (minutes > 0) {
    portions.push(minutes + 'm');
    duration = duration - (minutes * msInMinute);
  }

  const seconds = Math.trunc(duration / 1000);
  if (seconds > 0) {
    portions.push(seconds + 's');
  }

  return portions.join(' ');
}

console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion((60 * 60 * 1000) + (59 * 60 * 1000)              ));
console.log(timeConversion((60 * 60 * 1000)                                 ));
console.log(timeConversion((60 * 60 * 1000)                    + (59 * 1000)));
console.log(timeConversion(                   (59 * 60 * 1000) + (59 * 1000)));
console.log(timeConversion(                                      (59 * 1000)));

Upvotes: 16

Tin Pritišanac
Tin Pritišanac

Reputation: 399

Here is my solution

let h,m,s;
h = Math.floor(timeInMiliseconds/1000/60/60);
m = Math.floor((timeInMiliseconds/1000/60/60 - h)*60);
s = Math.floor(((timeInMiliseconds/1000/60/60 - h)*60 - m)*60);

// to get time format 00:00:00

s < 10 ? s = `0${s}`: s = `${s}`
m < 10 ? m = `0${m}`: m = `${m}`
h < 10 ? h = `0${h}`: h = `${h}`


console.log(`${s}:${m}:${h}`);

Upvotes: 26

Hassan
Hassan

Reputation: 330

Worked for me

msToTime(milliseconds) {
    //Get hours from milliseconds
    var hours = milliseconds / (1000*60*60);
    var absoluteHours = Math.floor(hours);
    var h = absoluteHours > 9 ? absoluteHours : '0' + absoluteHours;

    //Get remainder from hours and convert to minutes
    var minutes = (hours - absoluteHours) * 60;
    var absoluteMinutes = Math.floor(minutes);
    var m = absoluteMinutes > 9 ? absoluteMinutes : '0' +  absoluteMinutes;

    //Get remainder from minutes and convert to seconds
    var seconds = (minutes - absoluteMinutes) * 60;
    var absoluteSeconds = Math.floor(seconds);
    var s = absoluteSeconds > 9 ? absoluteSeconds : '0' + absoluteSeconds;

    return h == "00" ? m + ':' + s : h + ':' + m + ':' + s;
}

Upvotes: 3

lucataglia
lucataglia

Reputation: 792

In my implementation I used Moment.js:

export default (value) => 
  const duration = moment.duration(value);

  const milliseconds = duration.milliseconds();
  const seconds = duration.seconds();
  const minutes = duration.minutes();
  const hours = duration.hours();
  const day = duration.days();

  const sDay = `${day}d `;
  const sHours = (hours < 10) ? `0${hours}h ` : `${hours}h `;
  const sMinutes = (minutes < 10) ? `0${minutes}' ` : `${minutes}' `;
  const sSeconds = (seconds < 10) ? `0${seconds}" ` : `${seconds}" `;
  const sMilliseconds = `${milliseconds}ms`;

  ...
}

Once got the strings, I composed them as I want.

Upvotes: 0

Jonathan Biteau
Jonathan Biteau

Reputation: 1

If you're using typescript, this could be a good thing for you

enum ETime {
  Seconds = 1000,
  Minutes = 60000,
  Hours = 3600000,
  SecInMin = 60,
  MinInHours = 60,
  HoursMod = 24,
  timeMin = 10,
}

interface ITime {
  millis: number
  modulo: number
}

const Times = {
  seconds: {
    millis: ETime.Seconds,
    modulo: ETime.SecInMin,
  },
  minutes: {
    millis: ETime.Minutes,
    modulo: ETime.MinInHours,
  },
  hours: {
    millis: ETime.Hours,
    modulo: ETime.HoursMod,
  },
}

const dots: string = ":"

const msToTime = (duration: number, needHours: boolean = true): string => {
  const getCorrectTime = (divider: ITime): string => {
    const timeStr: number = Math.floor(
      (duration / divider.millis) % divider.modulo,
    )

    return timeStr < ETime.timeMin ? "0" + timeStr : String(timeStr)
  }

  return (
    (needHours ? getCorrectTime(Times.hours) + dots : "") +
    getCorrectTime(Times.minutes) +
    dots +
    getCorrectTime(Times.seconds)
  )
}

Upvotes: 0

Steven Spungin
Steven Spungin

Reputation: 29109

This solution uses one function to split milliseconds into a parts object, and another function to format the parts object.

I created 2 format functions, one as you requested, and another that prints a friendly string and considering singular/plural, and includes an option to show milliseconds.

function parseDuration(duration) {
  let remain = duration

  let days = Math.floor(remain / (1000 * 60 * 60 * 24))
  remain = remain % (1000 * 60 * 60 * 24)

  let hours = Math.floor(remain / (1000 * 60 * 60))
  remain = remain % (1000 * 60 * 60)

  let minutes = Math.floor(remain / (1000 * 60))
  remain = remain % (1000 * 60)

  let seconds = Math.floor(remain / (1000))
  remain = remain % (1000)

  let milliseconds = remain

  return {
    days,
    hours,
    minutes,
    seconds,
    milliseconds
  };
}

function formatTime(o, useMilli = false) {
  let parts = []
  if (o.days) {
    let ret = o.days + ' day'
    if (o.days !== 1) {
      ret += 's'
    }
    parts.push(ret)
  }
  if (o.hours) {
    let ret = o.hours + ' hour'
    if (o.hours !== 1) {
      ret += 's'
    }
    parts.push(ret)
  }
  if (o.minutes) {
    let ret = o.minutes + ' minute'
    if (o.minutes !== 1) {
      ret += 's'
    }
    parts.push(ret)

  }
  if (o.seconds) {
    let ret = o.seconds + ' second'
    if (o.seconds !== 1) {
      ret += 's'
    }
    parts.push(ret)
  }
  if (useMilli && o.milliseconds) {
    let ret = o.milliseconds + ' millisecond'
    if (o.milliseconds !== 1) {
      ret += 's'
    }
    parts.push(ret)
  }
  if (parts.length === 0) {
    return 'instantly'
  } else {
    return parts.join(' ')
  }
}

function formatTimeHMS(o) {
  let hours = o.hours.toString()
  if (hours.length === 1) hours = '0' + hours

  let minutes = o.minutes.toString()
  if (minutes.length === 1) minutes = '0' + minutes

  let seconds = o.seconds.toString()
  if (seconds.length === 1) seconds = '0' + seconds

  return hours + ":" + minutes + ":" + seconds
}

function formatDurationHMS(duration) {
  let time = parseDuration(duration)
  return formatTimeHMS(time)
}

function formatDuration(duration, useMilli = false) {
  let time = parseDuration(duration)
  return formatTime(time, useMilli)
}


console.log(formatDurationHMS(57742343234))

console.log(formatDuration(57742343234))
console.log(formatDuration(5423401000))
console.log(formatDuration(500))
console.log(formatDuration(500, true))
console.log(formatDuration(1000 * 30))
console.log(formatDuration(1000 * 60 * 30))
console.log(formatDuration(1000 * 60 * 60 * 12))
console.log(formatDuration(1000 * 60 * 60 * 1))

Upvotes: 5

Goran Jakovljevic
Goran Jakovljevic

Reputation: 2820

I needed time only up to one day, 24h, this was my take:

const milliseconds = 5680000;

const hours = `0${new Date(milliseconds).getHours() - 1}`.slice(-2);
const minutes = `0${new Date(milliseconds).getMinutes()}`.slice(-2);
const seconds = `0${new Date(milliseconds).getSeconds()}`.slice(-2);

const time = `${hours}:${minutes}:${seconds}`
console.log(time);

you could get days this way as well if needed.

Upvotes: 6

Frank Adrian
Frank Adrian

Reputation: 1234

The above snippets don't work for cases with more than 1 day (They are simply ignored).

For this you can use:

function convertMS(ms) {
    var d, h, m, s;
    s = Math.floor(ms / 1000);
    m = Math.floor(s / 60);
    s = s % 60;
    h = Math.floor(m / 60);
    m = m % 60;
    d = Math.floor(h / 24);
    h = h % 24;
    h += d * 24;
    return h + ':' + m + ':' + s;
}

enter image description here

Thanks to https://gist.github.com/remino/1563878

Upvotes: 8

Anastasis
Anastasis

Reputation: 729

Based on @Chand answer. This is the implementation in Typescript. A bit safer than coercing types in JS. If you remove the type annotation should be valid JS. Also using new string functions to normalise the time.

function displayTime(millisec: number) {
 const normalizeTime = (time: string): string => (time.length === 1) ? time.padStart(2, '0') : time;

 let seconds: string = (millisec / 1000).toFixed(0);
 let minutes: string = Math.floor(parseInt(seconds) / 60).toString();
 let hours: string = '';

 if (parseInt(minutes) > 59) {
   hours = normalizeTime(Math.floor(parseInt(minutes) / 60).toString());
   minutes = normalizeTime((parseInt(minutes) - (parseInt(hours) * 60)).toString());
 }
 seconds = normalizeTime(Math.floor(parseInt(seconds) % 60).toString());

 if (hours !== '') {
    return `${hours}:${minutes}:${seconds}`;
 }
   return `${minutes}:${seconds}`;
}

Upvotes: 2

Dan Alboteanu
Dan Alboteanu

Reputation: 10232

my solution

var sunriseMills = 1517573074000;         // sunrise in NewYork on Feb 3, 2018  - UTC time
var offsetCityMills = -5 * 3600 * 1000;   // NewYork delay to UTC 
var offsetDeviceMills =  new Date().getTimezoneOffset() * 60 * 1000 ;  // eg. I live in Romania (UTC+2) >> getTimezoneOffset() = 120

var textTime = new Date(sunriseMills + offsetCityMills + offsetDeviceMills) 
    .toLocaleTimeString('en-US', { hour: 'numeric', minute: 'numeric' });

textTime will become '7.04 AM'

Upvotes: 1

Chand
Chand

Reputation: 579

This one returns time like youtube videos

    function getYoutubeLikeToDisplay(millisec) {
        var seconds = (millisec / 1000).toFixed(0);
        var minutes = Math.floor(seconds / 60);
        var hours = "";
        if (minutes > 59) {
            hours = Math.floor(minutes / 60);
            hours = (hours >= 10) ? hours : "0" + hours;
            minutes = minutes - (hours * 60);
            minutes = (minutes >= 10) ? minutes : "0" + minutes;
        }

        seconds = Math.floor(seconds % 60);
        seconds = (seconds >= 10) ? seconds : "0" + seconds;
        if (hours != "") {
            return hours + ":" + minutes + ":" + seconds;
        }
        return minutes + ":" + seconds;
    }

Output:

  • getYoutubeLikeToDisplay(129900) = "2:10"
  • getYoutubeLikeToDisplay(1229900) = "20:30"
  • getYoutubeLikeToDisplay(21229900) = "05:53:50"

Upvotes: 22

xno
xno

Reputation: 1271

I had the same problem, this is what I ended up doing:

function parseMillisecondsIntoReadableTime(milliseconds){
  //Get hours from milliseconds
  var hours = milliseconds / (1000*60*60);
  var absoluteHours = Math.floor(hours);
  var h = absoluteHours > 9 ? absoluteHours : '0' + absoluteHours;

  //Get remainder from hours and convert to minutes
  var minutes = (hours - absoluteHours) * 60;
  var absoluteMinutes = Math.floor(minutes);
  var m = absoluteMinutes > 9 ? absoluteMinutes : '0' +  absoluteMinutes;

  //Get remainder from minutes and convert to seconds
  var seconds = (minutes - absoluteMinutes) * 60;
  var absoluteSeconds = Math.floor(seconds);
  var s = absoluteSeconds > 9 ? absoluteSeconds : '0' + absoluteSeconds;


  return h + ':' + m + ':' + s;
}


var time = parseMillisecondsIntoReadableTime(86400000);

alert(time);

Upvotes: 38

Related Questions