How to convert milliseconds into human readable form?

Viewed 159950

I need to convert an arbitrary amount of milliseconds into Days, Hours, Minutes Second.

For example: 10 Days, 5 hours, 13 minutes, 1 second.

22 Answers

Well, since nobody else has stepped up, I'll write the easy code to do this:

x = ms / 1000
seconds = x % 60
x /= 60
minutes = x % 60
x /= 60
hours = x % 24
x /= 24
days = x

I'm just glad you stopped at days and didn't ask for months. :)

Note that in the above, it is assumed that / represents truncating integer division. If you use this code in a language where / represents floating point division, you will need to manually truncate the results of the division as needed.

Let A be the amount of milliseconds. Then you have:

seconds=(A/1000)%60
minutes=(A/(1000*60))%60
hours=(A/(1000*60*60))%24

and so on (% is the modulus operator).

Hope this helps.

You should use the datetime functions of whatever language you're using, but, just for fun here's the code:

int milliseconds = someNumber;

int seconds = milliseconds / 1000;

int minutes = seconds / 60;

seconds %= 60;

int hours = minutes / 60;

minutes %= 60;

int days = hours / 24;

hours %= 24;

I would suggest using whatever date/time functions/libraries your language/framework of choice provides. Also check out string formatting functions as they often provide easy ways to pass date/timestamps and output a human readable string format.

Your choices are simple:

  1. Write the code to do the conversion (ie, divide by milliSecondsPerDay to get days and use the modulus to divide by milliSecondsPerHour to get hours and use the modulus to divide by milliSecondsPerMinute and divide by 1000 for seconds. milliSecondsPerMinute = 60000, milliSecondsPerHour = 60 * milliSecondsPerMinute, milliSecondsPerDay = 24 * milliSecondsPerHour.
  2. Use an operating routine of some kind. UNIX and Windows both have structures that you can get from a Ticks or seconds type value.

A solution using awk:

$ ms=10000001; awk -v ms=$ms 'BEGIN {x=ms/1000; 
                                     s=x%60; x/=60;
                                     m=x%60; x/=60;
                                     h=x%60;
                              printf("%02d:%02d:%02d.%03d\n", h, m, s, ms%1000)}'
02:46:40.001

This one leaves out 0 values. With tests.

const toTimeString = (value, singularName) =>
  `${value} ${singularName}${value !== 1 ? 's' : ''}`;

const readableTime = (ms) => {
  const days = Math.floor(ms / (24 * 60 * 60 * 1000));
  const daysMs = ms % (24 * 60 * 60 * 1000);
  const hours = Math.floor(daysMs / (60 * 60 * 1000));
  const hoursMs = ms % (60 * 60 * 1000);
  const minutes = Math.floor(hoursMs / (60 * 1000));
  const minutesMs = ms % (60 * 1000);
  const seconds = Math.round(minutesMs / 1000);

  const data = [
    [days, 'day'],
    [hours, 'hour'],
    [minutes, 'minute'],
    [seconds, 'second'],
  ];

  return data
    .filter(([value]) => value > 0)
    .map(([value, name]) => toTimeString(value, name))
    .join(', ');
};

// Tests
const hundredDaysTwentyHoursFiftyMinutesThirtySeconds = 8715030000;
const oneDayTwoHoursEightMinutesTwelveSeconds = 94092000;
const twoHoursFiftyMinutes = 10200000;
const oneMinute = 60000;
const fortySeconds = 40000;
const oneSecond = 1000;
const oneDayTwelveSeconds = 86412000;

const test = (result, expected) => {
  console.log(expected, '- ' + (result === expected));
};

test(readableTime(
  hundredDaysTwentyHoursFiftyMinutesThirtySeconds
), '100 days, 20 hours, 50 minutes, 30 seconds');

test(readableTime(
  oneDayTwoHoursEightMinutesTwelveSeconds
), '1 day, 2 hours, 8 minutes, 12 seconds');

test(readableTime(
  twoHoursFiftyMinutes
), '2 hours, 50 minutes');

test(readableTime(
  oneMinute
), '1 minute');

test(readableTime(
  fortySeconds
), '40 seconds');

test(readableTime(
  oneSecond
), '1 second');

test(readableTime(
  oneDayTwelveSeconds
), '1 day, 12 seconds');

Related