How to convert time in milliseconds to hours, min, sec format in JavaScript? - 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.

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))

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))

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);

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}`);

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"

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)));

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;
}
Thanks to https://gist.github.com/remino/1563878

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.

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

// 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`;
}

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))

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;
}

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))

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;
}

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}`;
}

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.

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'

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 seconds 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');

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)
)
}

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.

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
}

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}`
}

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"

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');
}

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)));

Related

Get difference between two times with ss.[milisecond] format [duplicate]

I have this function which formats seconds to time
function secondsToTime(secs){
var hours = Math.floor(secs / (60 * 60));
var divisor_for_minutes = secs % (60 * 60);
var minutes = Math.floor(divisor_for_minutes / 60);
var divisor_for_seconds = divisor_for_minutes % 60;
var seconds = Math.ceil(divisor_for_seconds);
return minutes + ":" + seconds;
}
it works great but i need a function to turn milliseconds to time and I cant seem to understand what i need to do to this function to return time in this format
mm:ss.mill
01:28.5568
Lots of unnecessary flooring in other answers. If the string is in milliseconds, convert to h:m:s as follows:
function msToTime(s) {
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return hrs + ':' + mins + ':' + secs + '.' + ms;
}
If you want it formatted as hh:mm:ss.sss then use:
function msToTime(s) {
// Pad to 2 or 3 digits, default is 2
function pad(n, z) {
z = z || 2;
return ('00' + n).slice(-z);
}
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return pad(hrs) + ':' + pad(mins) + ':' + pad(secs) + '.' + pad(ms, 3);
}
console.log(msToTime(55018))
Using some recently added language features, the pad function can be more concise:
function msToTime(s) {
// Pad to 2 or 3 digits, default is 2
var pad = (n, z = 2) => ('00' + n).slice(-z);
return pad(s/3.6e6|0) + ':' + pad((s%3.6e6)/6e4 | 0) + ':' + pad((s%6e4)/1000|0) + '.' + pad(s%1000, 3);
}
// Current hh:mm:ss.sss UTC
console.log(msToTime(new Date() % 8.64e7))
Here is my favourite one-liner solution:
new Date(12345 * 1000).toISOString().slice(11, -1); // "03:25:45.000"
Method Date.prototype.toISOString() returns a string in the simplified extended ISO format (ISO 8601), which is always 24 characters long: YYYY-MM-DDTHH:mm:ss.sssZ. This method is supported in all modern browsers (IE9+) and Node.
This one-liner is limited to a range of one day, which is fine if you use it to format milliseconds up to 24 hours (i.e. ms < 86400000). The following code is able to format correctly any number of milliseconds (shaped in a handy prototype method):
/**
* Convert (milli)seconds to time string (hh:mm:ss[:mss]).
*
* #param Boolean seconds
*
* #return String
*/
Number.prototype.toTimeString = function(seconds) {
var _24HOURS = 8.64e7; // 24*60*60*1000
var ms = seconds ? this * 1000 : this,
endPos = ~(4 * !!seconds), // to trim "Z" or ".sssZ"
timeString = new Date(ms).toISOString().slice(11, endPos);
if (ms >= _24HOURS) { // to extract ["hh", "mm:ss[.mss]"]
var parts = timeString.split(/:(?=\d{2}:)/);
parts[0] -= -24 * Math.floor(ms / _24HOURS);
timeString = parts.join(":");
}
return timeString;
};
console.log( (12345 * 1000).toTimeString() ); // "03:25:45.000"
console.log( (123456 * 789).toTimeString() ); // "27:03:26.784"
console.log( 12345. .toTimeString(true) ); // "03:25:45"
console.log( 123456789. .toTimeString(true) ); // "34293:33:09"
function millisecondsToTime(milli)
{
var milliseconds = milli % 1000;
var seconds = Math.floor((milli / 1000) % 60);
var minutes = Math.floor((milli / (60 * 1000)) % 60);
return minutes + ":" + seconds + "." + milliseconds;
}
Why not use the Date object like this?
let getTime = (milli) => {
let time = new Date(milli);
let hours = time.getUTCHours();
let minutes = time.getUTCMinutes();
let seconds = time.getUTCSeconds();
let milliseconds = time.getUTCMilliseconds();
return hours + ":" + minutes + ":" + seconds + ":" + milliseconds;
}
https://jsfiddle.net/4sdkpso7/6/
function millisecondsToTime(millisecs){
var ms = Math.abs(millisecs) % 1000;
var secs = (millisecs < 0 ? -1 : 1) * ((Math.abs(millisecs) - ms) / 1000);
ms = '' + ms;
ms = '000'.substring(ms.length) + ms;
return secsToTime(secs) + '.' + ms;
}
Here is a filter that use:
app.filter('milliSecondsToTimeCode', function () {
return function msToTime(duration) {
var milliseconds = parseInt((duration % 1000) / 100)
, seconds = parseInt((duration / 1000) % 60)
, minutes = parseInt((duration / (1000 * 60)) % 60)
, hours = parseInt((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;
};
});
Just add it to your expression as such
{{milliseconds | milliSecondsToTimeCode}}
Editing RobG's solution and using JavaScript's Date().
function msToTime(ms) {
function addZ(n) {
return (n<10? '0':'') + n;
}
var dt = new Date(ms);
var hrs = dt.getHours();
var mins = dt.getMinutes();
var secs = dt.getSeconds();
var millis = dt.getMilliseconds();
var tm = addZ(hrs) + ':' + addZ(mins) + ':' + addZ(secs) + "." + millis;
return tm;
}
Prons:
simple and clean code; easy to modify for your needs
support any amount of hours (>24 hrs is ok)
format time as 00:00:00.0
You can put it into a helper file
export const msecToTime = ms => {
const milliseconds = ms % 1000
const seconds = Math.floor((ms / 1000) % 60)
const minutes = Math.floor((ms / (60 * 1000)) % 60)
const hours = Math.floor((ms / (3600 * 1000)) % 3600)
return `${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}:${
seconds < 10 ? '0' + seconds : seconds
}.${milliseconds}`
}
This worked for me:
var dtFromMillisec = new Date(secs*1000);
var result = dtFromMillisec.getHours() + ":" + dtFromMillisec.getMinutes() + ":" + dtFromMillisec.getSeconds();
JSFiddle
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
export function getFormattedDateAndTime(startDate) {
if (startDate != null) {
var launchDate = new Date(startDate);
var day = launchDate.getUTCDate();
var month = monthNames[launchDate.getMonth()];
var year = launchDate.getFullYear();
var min = launchDate.getMinutes();
var hour = launchDate.getHours();
var time = launchDate.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true });
return day + " " + month + " " + year + " - " + time + "" ;
}
return "";
}
function msToTime(s) {
var d = new Date(s);
var datestring = ("0" + d.getDate()).slice(-2) + "-" + ("0"+(d.getMonth()+1)).slice(-2) + "-" +
d.getFullYear() + " "
+ ("0" + d.getHours()).slice(-2)
+ ":" + ("0" + d.getMinutes()).slice(-2)
+ ":" + ("0" + d.getSeconds()).slice(-2)
+"."+d.getMilliseconds();
return datestring;
}
output
16-10-2019 18:55:32.605
var
/**
* Parses time in milliseconds to time structure
* #param {Number} ms
* #returns {Object} timeStruct
* #return {Integer} timeStruct.d days
* #return {Integer} timeStruct.h hours
* #return {Integer} timeStruct.m minutes
* #return {Integer} timeStruct.s seconds
*/
millisecToTimeStruct = function (ms) {
var d, h, m, s;
if (isNaN(ms)) {
return {};
}
d = ms / (1000 * 60 * 60 * 24);
h = (d - ~~d) * 24;
m = (h - ~~h) * 60;
s = (m - ~~m) * 60;
return {d: ~~d, h: ~~h, m: ~~m, s: ~~s};
},
toFormattedStr = function(tStruct){
var res = '';
if (typeof tStruct === 'object'){
res += tStruct.m + ' min. ' + tStruct.s + ' sec.';
}
return res;
};
// client code:
var
ms = new Date().getTime(),
timeStruct = millisecToTimeStruct(ms),
formattedString = toFormattedStr(timeStruct);
alert(formattedString);
var secondsToTime = function(duration) {
var date = new Date(duration);
return "%hours:%minutes:%seconds:%milliseconds"
.replace('%hours', date.getHours())
.replace('%minutes', date.getMinutes())
.replace('%seconds', date.getSeconds())
.replace('%milliseconds', date.getMilliseconds());
}
try this function :-
function msToTime(ms) {
var d = new Date(null)
d.setMilliseconds(ms)
return d.toLocaleTimeString("en-US")
}
var ms = 4000000
alert(msToTime(ms))
A possible solution that worked for my case. It turns milliseconds into hh:ss time:
function millisecondstotime(ms) {
var x = new Date(ms);
var y = x.getHours();
if (y < 10) {
y = '0' + y;
}
var z = x.getMinutes();
if (z < 10) {
z = '0' + z;
}
return y + ':' + z;
}
This is the solution I got and working so good!
function msToHuman(duration) {
var milliseconds = parseInt((duration%1000)/100)
seconds = parseInt((duration/1000)%60)
minutes = parseInt((duration/(1000*60))%60)
hours = parseInt((duration/(1000*60*60))%24);
return hours + "hrs " minutes + "min " + seconds + "sec " + milliseconds + 'ms';
}
Most of the answers don't cover cases where there is more than 24h. This one does.
I suggest extending Date object:
class SuperDate extends Date {
get raceTime() {
return Math.floor(this/36e5).toString().padStart(2,'0')
+ this.toISOString().slice(13, -1)
}
}
console.log('marathon', new SuperDate(11235200).raceTime)
console.log('ironman', new SuperDate(40521100).raceTime)
console.log('spartathlon', new SuperDate(116239000).raceTime)
console.log('epoch', new SuperDate(new Date()).raceTime)
This approach works great with Firestore Timestamp objects which are similar to what you need:
class SuperDate extends Date {
fromFirestore (timestamp) {
return new SuperDate(timestamp.seconds * 1000 + timestamp.nanoseconds / 1000000)
}
get raceTime() {
return Math.floor(this/36e5).toString().padStart(2,'0')
+ this.toISOString().slice(13, -1)
}
}
const timestamp = {seconds: 11235, nanoseconds: 200000000}
console.log('timestamp', new SuperDate().fromFirestore(timestamp))
console.log('marathon', new SuperDate().fromFirestore(timestamp).raceTime)
Simplest Way
let getTime = (Time)=>{
let Hours = Time.getHours();
let Min = Time.getMinutes();
let Sec = Time.getSeconds();
return `Current time ${Hours} : ${Min} : ${Sec}`;
}
console.log(getTime(new Date()));
An Easier solution would be the following:
var d = new Date();
var n = d.getMilliseconds();

Is it possible to return compared value + a string from a ternary operation without repeating said value?

I'm trying to find an easier solution to a problem.
Problem:
I want to attempt and simplify this but I have no idea where to start.
let days = Math.floor(distance / (1000 * 60 * 60 * 24));
if(days > 0) {
days = days + "d";
}
Attempt:
I was thinking I could use ternary operators to return the calculation + "d" like so:
let days = Math.floor(distance / (1000 * 60 * 60 * 24)) === 0 ? Math.floor(distance / (1000 * 60 * 60 * 24)) + "d" : "";
this is however very messy in my opinion and I can't figure out another way.
Current structure
I am currently calculating days, hours, minutes and seconds for a timer like this:
let distance = expiry - now;
let days = Math.floor(distance / (1000 * 60 * 60 * 24));
let hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((distance % (1000 * 60)) / 1000);
After that I want to only show days if it's greater than 0 or minutes if it's greater than 0 and so on. I'm currently doing it with a bunch of if statements and a boolean to check if a value greater than 0 has been found already. Like so:
let isSet = false;
if (days > 0 && !isSet) {
current = days + "d";
isSet = true;
}
if (hours > 0 && !isSet) {
current = hours + "h";
isSet = true;
}
if (minutes > 0 && !isSet) {
current = minutes + "m";
isSet = true;
}
if (seconds > 0 && !isSet) {
current = seconds + "s";
isSet = true;
}
if (seconds < 0 && !isSet) {
current = "expired";
isSet = true;
}
This does however feel very repetitive and wrong (even if it works).
I think the best solution for patterns like this, is to define the ranges in an array, then compare against it, to avoid code duplication.
var ranges = [
[86400000, 'd'],
[3600000, 'h'],
[60000, 'm'],
[1000, 's'],
]
Then loop over this array and check if the provided value is greater than the current period.
function humanDiff(milliseconds) {
for (var i = 0; i < ranges.length; i++) {
if (milliseconds >= ranges[i][0]) {
return Math.round((milliseconds / ranges[i][0])) + ranges[i][1]
};
}
return milliseconds;
}
Example:
var expiry = new Date('2019-03-26 08:29');
var now = new Date('2019-03-26 05:00');
humanDiff(expiry - now) // 3h
Advantages:
Avoid unnecessary calculations (don't calculate hours and minutes when days are appropriate)
Avoid code repetition
Separate the setup from the execution (adding more metrics is as easy as adding a new record in the ranges array)
Instead of storing the information as variables you could store them as properties of an object. You can then iterate through each property and just set the text you wish.
const dateInfo = {
days: 1E3 * 60 * 60 * 24,
hours: 1E3 * 60 * 60,
minutes: 1E3 * 60,
seconds: 1E3
};
function check(distance) {
return Object.keys(dateInfo).reduce(function(result, key) {
result[key] = Math.floor(distance / dateInfo[key]);
distance -= dateInfo[key] * result[key];
result[key] = result[key] > 0 ? `${result[key]}${key}` : "";
return result;
}, {});
}
let result = check(1E9);
console.log(result); // result
console.log(Object.values(result).join(" ")); // Print all properties
console.log(Object.values(result).find(item => item) || "Expired"); // Print first property
The most efficient and compact way is:
const dateInfo = {
d: 1E3 * 60 * 60 * 24,
h: 1E3 * 60 * 60,
m: 1E3 * 60,
s: 1E3
};
function check(distance) {
// Find the biggest proprty that is still smaller than the total difference
var key = Object.keys(dateInfo).find(key => dateInfo[key] <= distance);
// No need for % since distance > dateInfo[key]
return `${Math.floor(distance / dateInfo[key]) || "expired"}${key || ""}`;
}
console.log(check(3E9)); //34d
console.log(check(3E7)); //8h
console.log(check(3E5)); //5m
console.log(check(3E3)); //3s
console.log(check(3E0)); //expired
You may use conditional spread
const now = new Date(2018, 1, 5, 10, 11);
const expiry = new Date(2018, 2, 5, 5, 6);
let distance = expiry - now;
let days = Math.floor(distance / (1000 * 60 * 60 * 24));
let hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((distance % (1000 * 60)) / 1000);
const arr = [
...(days > 0 ? [days + "d"] : []),
...(hours > 0 ? [hours + "h"] : []),
...(minutes > 0 ? [minutes + "m"] : []),
...(seconds > 0 ? [seconds + "s"] : []),
];
const current = arr.length ? arr.join(' ') : "expired";
console.log(current);
getDurationDetails:function(duration){
var result = [];
var units = {
Year:31536000,
Month:2592000,
Week:604800,
Day: 86400,
Hour: 3600,
Minute: 60,
Second:1,
};
for(var name in units) {
var res = Math.floor(duration/units[name]);
if(res == 1) result.push(" " + res + " " + name);
if(res >= 2) result.push(" " + res + " " + name + "s");
duration %= units[name];
}
return result;
},
try this one
Your biggest issue is the isSet variable, not that you are using an if statement.
Instead of setting isSet, you should just use else:
var current;
if (days > 0) {
current = days + "d";
} else if (hours > 0) {
current = hours + "h";
} else if (minutes > 0) {
current = minutes + "m";
} else if (seconds > 0) {
current = seconds + "s";
} else if (seconds < 0) {
current = "expired";
} // else seconds == 0
You might want to use conditional operators here. You should not try to merge them into the days = Math.floor(distance / (1000 * 60 * 60 * 24)) computation, leave that as is - days is just a temporary variable. Store the result of the conditional in a different variable (current), not in days:
const distance = expiry - now;
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
const current =
(days > 0) ? days + "d" :
(hours > 0) ? hours + "h" :
(minutes > 0) ? minutes + "m" :
(seconds > 0) ? seconds + "s" :
//(seconds == 0) ? undefined :
"expired";
A waterfall method such as you have is not a bad idea. I would modify it to update the distance variable when you add to the string, such as this (e.g. 4d 3h 17m 1s):
function formatDuration (seconds) {
let s = seconds, r = '', t;
if (s % 86400 !== s) updateR('d', 86400);
if (s % 3600 !== s) updateR('h', 3600);
if (s % 60 !== s) updateR('m', 60);
if (s > 0) updateR('s', 1);
function updateR(unit, n) {
t = Math.floor(s / n);
s %= n;
r += (r === '' ? '' : ' ') + t + unit;
}
return r.replace(/,\s(?=\d{1,2}\s\w+$)/, ' and ') || 'expired';
}
And a more expressive version (e.g. 4 days, 3 hours, 17 minutes, and 1 second):
function formatDuration (seconds) {
let s = seconds, r = '', t;
// if (s % 31536000 !== s) updateR(' year', 31536000);
if (s % 86400 !== s) updateR(' day', 86400);
if (s % 3600 !== s) updateR(' hour', 3600);
if (s % 60 !== s) updateR(' minute', 60);
if (s > 0) updateR(' second', 1);
function updateR(unit, n) {
t = Math.floor(s / n);
s %= n;
r += (r === '' ? '' : ', ') + t + unit + (t === 1 ? '' : 's');
}
return r.replace(/,\s(?=\d{1,2}\s\w+$)/, ' and ') || 'expired';
}
You could take an array of the values and if you find an index, take this index as accessor for the value and the postfix or take 'expired' as value.
let distance = expiry - now,
factors = [86400000, 3600000, 60000, 1000],
values = factors.map(f => [Math.floor(distance / f), distance %= f][0]),
index = values.findIndex(v => v > 0),
result = index === -1 ? 'expired' : value[index] + 'DHMS'[index];
console.log(result);

how to converting a value to hr:mn:sc format in javascript

I want to convert the value of album.songs[i].duration in the following code so it displays hr:mn:sc instead of the format it is stored in, which is seconds. Can I do this in this line of code?
var $newRow = createSongRow(i + 1, album.songs[i].title, album.songs[i].duration);
This is basic math...
function convert(s) {
var hr = (Math.floor(s / 3600));
var mn = (Math.floor(s % 3600 / 60));
var sc = (Math.floor(s % 60));
return hr +":"+ mn +":"+ sc;
}
/* for example */
var seconds = 345432;
console.log(convert(seconds));
Considering that you want to convert a duration (in seconds) in the format of hr:mn:sc, we can follow the below approach in vanilla javascript:
var duration = 5000; // seconds
var hour = parseInt(duration / 3600); // as 1 hour = 3600 seconds
var minutes = parseInt((duration - (hour * 3600)) / 60); // as 1 minute = 60 seconds
var seconds = duration - (hour * 3600) - (minutes * 60);
var durationStr = hour + ':' + minutes + ':' + seconds;
console.log(durationStr); // should print 1:23:20
Expanding on Hearner's answer, with padding for minutes and seconds < 10:
function pad(num) {
if (num < 10) return '0' + num;
return num;
}
function convert(s) {
var hr = (Math.floor(s / 3600));
var mn = pad(Math.floor(s % 3600 / 60));
var sc = pad(Math.floor(s % 60));
return hr +":"+ mn +":"+ sc;
}
/* for example */
var seconds = 3661;
console.log(convert(seconds)); // 1:01:01 instead of 1:1:1
// and you would use:
// var $newRow = createSongRow(i + 1, album.songs[i].title, convert(album.songs[i].duration));

How do I return process.uptime(); from milliseconds into a human readable format?

I'm making a discord bot. I've tried this -
bot.on('message', message => {
if (message.content === '!uptime') {
var time = process.uptime();
function dhm(ms) {
days = Math.floor(ms / (24 * 60 * 60 * 1000));
daysms = ms % (24 * 60 * 60 * 1000);
hours = Math.floor((daysms) / (60 * 60 * 1000));
hoursms = ms % (60 * 60 * 1000);
minutes = Math.floor((hoursms) / (60 * 1000));
minutesms = ms % (60 * 1000);
sec = Math.floor((minutesms) / (1000));
return days + ":" + hours + ":" + minutes + ":" + sec;
}
message.channel.sendMessage(dhm(time));
}
});
In chat, this returns - 0:0:0:0
// Uptime
bot.on('message', message => {
if (message.content === '!uptime') {
var time = process.uptime();
function dhm(t){
var cd = 24 * 60 * 60 * 1000,
ch = 60 * 60 * 1000,
d = Math.floor(t / cd),
h = Math.floor( (t - d * cd) / ch),
m = Math.round( (t - d * cd - h * ch) / 60000),
pad = function(n){ return n < 10 ? '0' + n : n; };
if( m === 60 ){
h++;
m = 0;
}
if( h === 24 ){
d++;
h = 0;
}
return [d, pad(h), pad(m)].join(':');
}
message.channel.sendMessage(dhm(time));
}});
This returns 0:00:00
I'm trying to convert the value of process.uptime(); into days, hours, minutes, and seconds. Any help will be appreciated.
Btw, the first comment given is not 100% correct. According to the latest documentation the return value includes fractions of a second. Math.floor() should be used to obtain whole seconds. Thus, to obtain the uptime in milliseconds the process.uptime() value needs to be multiplied by 1000. The following code example may do what you want. As the example uses a different format you may want to adapt the code to the format you prefer which should be straightformward.
You can trial a variation of this code on repl.it
var uptime = process.uptime();
console.log("Uptime raw:", uptime)
const date = new Date(uptime*1000);
const days = date.getUTCDate() - 1,
hours = date.getUTCHours(),
minutes = date.getUTCMinutes(),
seconds = date.getUTCSeconds(),
milliseconds = date.getUTCMilliseconds();
let segments = [];
if (days > 0) segments.push(days + ' day' + ((days == 1) ? '' : 's'));
if (hours > 0) segments.push(hours + ' hour' + ((hours == 1) ? '' : 's'));
if (minutes > 0) segments.push(minutes + ' minute' + ((minutes == 1) ? '' : 's'));
if (seconds > 0) segments.push(seconds + ' second' + ((seconds == 1) ? '' : 's'));
if (milliseconds > 0) segments.push(milliseconds + ' millisecond' + ((seconds == 1) ? '' : 's'));
const dateString = segments.join(', ');
console.log("Uptime: " + dateString);

Convert time interval given in seconds into more human readable form

I need a code snippet for converting amount of time given by number of seconds into some human readable form. The function should receive a number and output a string like this:
34 seconds
12 minutes
4 hours
5 days
4 months
1 year
No formatting required, hard-coded format will go.
function secondsToString(seconds)
{
var numyears = Math.floor(seconds / 31536000);
var numdays = Math.floor((seconds % 31536000) / 86400);
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60;
return numyears + " years " + numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";
}
With help of Royi we've got code that outputs time interval in a human readable form:
function millisecondsToStr (milliseconds) {
// TIP: to find current time in milliseconds, use:
// var current_time_milliseconds = new Date().getTime();
function numberEnding (number) {
return (number > 1) ? 's' : '';
}
var temp = Math.floor(milliseconds / 1000);
var years = Math.floor(temp / 31536000);
if (years) {
return years + ' year' + numberEnding(years);
}
//TODO: Months! Maybe weeks?
var days = Math.floor((temp %= 31536000) / 86400);
if (days) {
return days + ' day' + numberEnding(days);
}
var hours = Math.floor((temp %= 86400) / 3600);
if (hours) {
return hours + ' hour' + numberEnding(hours);
}
var minutes = Math.floor((temp %= 3600) / 60);
if (minutes) {
return minutes + ' minute' + numberEnding(minutes);
}
var seconds = temp % 60;
if (seconds) {
return seconds + ' second' + numberEnding(seconds);
}
return 'less than a second'; //'just now' //or other string you like;
}
If you are interested in an existing javascript library that does the job very well, you may want to check moment.js.
More specifically, the relevant moment.js piece for your question is durations.
Here are some examples of how you can take advantage of it to achieve your task:
var duration = moment.duration(31536000);
// Using the built-in humanize function:
console.log(duration.humanize()); // Output: "9 hours"
console.log(duration.humanize(true)); // Output: "in 9 hours"
moment.js has built-in support for 50+ human languages, so if you use the humanize() method you get multi-language support for free.
If you want to display the exact time information, you can take advantage of the moment-precise-range plug-in for moment.js that was created exactly for this purpose:
console.log(moment.preciseDiff(0, 39240754000);
// Output: 1 year 2 months 30 days 5 hours 12 minutes 34 seconds
One thing to note is that currently moment.js does not support weeks / days (in week) for duration object.
Hope this helps!
Took a swing based on #Royi's response:
/**
* Translates seconds into human readable format of seconds, minutes, hours, days, and years
*
* #param {number} seconds The number of seconds to be processed
* #return {string} The phrase describing the amount of time
*/
function forHumans ( seconds ) {
var levels = [
[Math.floor(seconds / 31536000), 'years'],
[Math.floor((seconds % 31536000) / 86400), 'days'],
[Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'],
[Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'],
[(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'],
];
var returntext = '';
for (var i = 0, max = levels.length; i < max; i++) {
if ( levels[i][0] === 0 ) continue;
returntext += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length-1): levels[i][1]);
};
return returntext.trim();
}
Nice thing about mine is that there is no repetitive ifs, and won't give you 0 years 0 days 30 minutes 1 second for example.
For example:
forHumans(60) outputs 1 minute
forHumans(3600) outputs 1 hour
and forHumans(13559879) outputs 156 days 22 hours 37 minutes 59 seconds
Try following:
seconds = ~~(milliseconds / 1000);
minutes = ~~(seconds / 60);
hours = ~~(minutes / 60);
days = ~~(hours / 24);
weeks = ~~(days / 7);
year = ~~(days / 365);
Note:
A usual year has 365 days. A leap year has 366 days, so you need additional check if this is an issue for you.
The similar problem with daylight saving. Some days have 23 and some 25 hours when time's changed.
Conclusion: this is a rude but small and simple snippet :)
millisToTime = function(ms){
x = ms / 1000;
seconds = Math.round(x % 60);
x /= 60;
minutes = Math.round(x % 60);
x /= 60;
hours = Math.round(x % 24);
x /= 24;
days = Math.round(x);
return {"Days" : days, "Hours" : hours, "Minutes" : minutes, "Seconds" : seconds};
}
This will take milliseconds as an int, and give you an JSON object containing all the info you could need
Way more simple and readable.
milliseconds = 12345678;
mydate=new Date(milliseconds);
humandate=mydate.getUTCHours()+" hours, "+mydate.getUTCMinutes()+" minutes and "+mydate.getUTCSeconds()+" second(s)";
Which gives:
"3 hours, 25 minutes and 45 second(s)"
To Convert time in millisecond to human readable format.
function timeConversion(millisec) {
var seconds = (millisec / 1000).toFixed(1);
var minutes = (millisec / (1000 * 60)).toFixed(1);
var hours = (millisec / (1000 * 60 * 60)).toFixed(1);
var days = (millisec / (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"
}
}
Thanks to #Dan / # Royi for the logic. However the implementation doesn't build time string like XX days, XX mins. I adjusted their code a bit:
function millisecondsToStr( milliseconds ) {
let temp = milliseconds / 1000;
const years = Math.floor( temp / 31536000 ),
days = Math.floor( ( temp %= 31536000 ) / 86400 ),
hours = Math.floor( ( temp %= 86400 ) / 3600 ),
minutes = Math.floor( ( temp %= 3600 ) / 60 ),
seconds = temp % 60;
if ( days || hours || seconds || minutes ) {
return ( years ? years + "y " : "" ) +
( days ? days + "d " : "" ) +
( hours ? hours + "h " : "" ) +
( minutes ? minutes + "m " : "" ) +
Number.parseFloat( seconds ).toFixed( 2 ) + "s";
}
return "< 1s";
}
When one runs it
console.log("=", millisecondsToStr( 1540545689739 - 1540545684368 ));
console.log("=", millisecondsToStr( 351338536000 ));
The results look like:
= 5.37s
= 11y 51d 10h 2m 16.00s
Adding to the myriad of methods, here's a cheap and short way to retrieve a human readable time with only a single time unit.
const timeScalars = [1000, 60, 60, 24, 7, 52];
const timeUnits = ['ms', 'secs', 'mins', 'hrs', 'days', 'weeks', 'years'];
const getHumanReadableTime = (ms, dp = 0) => {
let timeScalarIndex = 0, scaledTime = ms;
while (scaledTime > timeScalars[timeScalarIndex]) {
scaledTime /= timeScalars[timeScalarIndex++];
}
return `${scaledTime.toFixed(dp)} ${timeUnits[timeScalarIndex]}`;
};
Example outputs:
getHumanReadableTime(512000);
getHumanReadableTime(5120000);
getHumanReadableTime(51200000);
getHumanReadableTime(51200000, 2);
getHumanReadableTime(51200000, 6);
/*
Output:
'9 min'
'1 hrs'
'14 hrs'
'14.22 hrs'
'14.222222 hrs'
*/
function millisecondsToString(milliseconds) {
var oneHour = 3600000;
var oneMinute = 60000;
var oneSecond = 1000;
var seconds = 0;
var minutes = 0;
var hours = 0;
var result;
if (milliseconds >= oneHour) {
hours = Math.floor(milliseconds / oneHour);
}
milliseconds = hours > 0 ? (milliseconds - hours * oneHour) : milliseconds;
if (milliseconds >= oneMinute) {
minutes = Math.floor(milliseconds / oneMinute);
}
milliseconds = minutes > 0 ? (milliseconds - minutes * oneMinute) : milliseconds;
if (milliseconds >= oneSecond) {
seconds = Math.floor(milliseconds / oneSecond);
}
milliseconds = seconds > 0 ? (milliseconds - seconds * oneSecond) : milliseconds;
if (hours > 0) {
result = (hours > 9 ? hours : "0" + hours) + ":";
} else {
result = "00:";
}
if (minutes > 0) {
result += (minutes > 9 ? minutes : "0" + minutes) + ":";
} else {
result += "00:";
}
if (seconds > 0) {
result += (seconds > 9 ? seconds : "0" + seconds) + ":";
} else {
result += "00:";
}
if (milliseconds > 0) {
result += (milliseconds > 9 ? milliseconds : "0" + milliseconds);
} else {
result += "00";
}
return result;
}
Here is my take.
Feel free to play around with it in the jsbin.
// This returns a string representation for a time interval given in milliseconds
// that appeals to human intuition and so does not care for leap-years,
// month length irregularities and other pesky nuisances.
const human_millis = function (ms, digits=1) {
const levels=[
["ms", 1000],
["sec", 60],
["min", 60],
["hrs", 24],
["days", 7],
["weeks", (30/7)], // Months are intuitively around 30 days
["months", 12.1666666666666666], // Compensate for bakari-da in last step
["years", 10],
["decades", 10],
["centuries", 10],
["millenia", 10],
];
var value=ms;
var name="";
var step=1;
for(var i=0, max=levels.length;i<max;++i){
value/=step;
name=levels[i][0];
step=levels[i][1];
if(value < step){
break;
}
}
return value.toFixed(digits)+" "+name;
}
console.clear();
console.log("---------");
console.log(human_millis(1));
console.log(human_millis(10));
console.log(human_millis(100));
console.log(human_millis(1000));
console.log(human_millis(1000*60));
console.log(human_millis(1000*60*60));
console.log(human_millis(1000*60*60*24));
console.log(human_millis(1000*60*60*24*7));
console.log(human_millis(1000*60*60*24*30));
console.log(human_millis(1000*60*60*24*365));
console.log(human_millis(1000*60*60*24*365*10));
console.log(human_millis(1000*60*60*24*365*10*10));
console.log(human_millis(1000*60*60*24*365*10*10*10));
console.log(human_millis(1000*60*60*24*365*10*10*10*10));
If you use Typescript type and cast to make it work
let name : string | number = "";
let step : string | number =1;
for(var i=0, max=levels.length;i<max;++i){
value/= step as number;
name=levels[i][0];
step=levels[i][1];
if(value < step){
break;
}
}
Output:
"---------"
"1.0 ms"
"10.0 ms"
"100.0 ms"
"1.0 sec"
"1.0 min"
"1.0 hrs"
"1.0 days"
"1.0 weeks"
"1.0 months"
"1.0 years"
"1.0 decades"
"1.0 centuries"
"1.0 millenia"
"10.0 millenia"
This function outputs seconds in this format : 11h 22m, 1y 244d, 42m 4s etc
Set the max variable to show as many identifiers as you want.
function secondsToString (seconds) {
var years = Math.floor(seconds / 31536000);
var max =2;
var current = 0;
var str = "";
if (years && current<max) {
str+= years + 'y ';
current++;
}
var days = Math.floor((seconds %= 31536000) / 86400);
if (days && current<max) {
str+= days + 'd ';
current++;
}
var hours = Math.floor((seconds %= 86400) / 3600);
if (hours && current<max) {
str+= hours + 'h ';
current++;
}
var minutes = Math.floor((seconds %= 3600) / 60);
if (minutes && current<max) {
str+= minutes + 'm ';
current++;
}
var seconds = seconds % 60;
if (seconds && current<max) {
str+= seconds + 's ';
current++;
}
return str;
}
With the help of Dan answer, I came up with this if you want to calculate the difference between the post created time (from DB it should be retrieved as UTC) and the users system time and then show them the elapsed time, you could use below function
function dateToStr(input_date) {
input_date= input_date+" UTC";
// convert times in milliseconds
var input_time_in_ms = new Date(input_date).getTime();
var current_time_in_ms = new Date().getTime();
var elapsed_time = current_time_in_ms - input_time_in_ms;
function numberEnding (number) {
return (number > 1) ? 's' : '';
}
var temp = Math.floor(elapsed_time / 1000);
var years = Math.floor(temp / 31536000);
if (years) {
return years + ' year' + numberEnding(years);
}
//TODO: Months! Maybe weeks?
var days = Math.floor((temp %= 31536000) / 86400);
if (days) {
return days + ' day' + numberEnding(days);
}
var hours = Math.floor((temp %= 86400) / 3600);
if (hours) {
return hours + ' hour' + numberEnding(hours);
}
var minutes = Math.floor((temp %= 3600) / 60);
if (minutes) {
return minutes + ' minute' + numberEnding(minutes);
}
var seconds = temp % 60;
if (seconds) {
return seconds + ' second' + numberEnding(seconds);
}
return 'less than a second'; //'just now' //or other string you like;
}
eg: usage
var str = dateToStr('2014-10-05 15:22:16');
There is the Intl.RelativeTimeFormat API, which is supported in recent versions of Chrome and Firefox.
An few examples:
let rtf = new Intl.RelativeTimeFormat("en");
rtf.format(-1, "day"); // 'yesterday'
rtf.format(-2, 'day'); // '2 days ago'
rtf.format(13.37, 'second'); // 'in 13.37 seconds'
And there's a lot more in this blog post and in the proposal itself.
To show only what you need and not day 0, hours 0...
formatTime = function(time) {
var ret = time % 1000 + ' ms';
time = Math.floor(time / 1000);
if (time !== 0) {
ret = time % 60 + "s "+ret;
time = Math.floor(time / 60);
if (time !== 0) {
ret = time % 60 + "min "+ret;
time = Math.floor(time / 60);
if (time !== 0) {
ret = time % 60 + "h "+ret;
...
}
}
}
return ret;
};
Following a similar approach to #Dan, I have modified #Royi Namir's code to output a string with commas and and's:
secondsToString = function(seconds) {
var numdays, numhours, nummilli, numminutes, numseconds, numyears, res;
numyears = Math.floor(seconds / 31536000);
numdays = Math.floor(seconds % 31536000 / 86400);
numhours = Math.floor(seconds % 31536000 % 86400 / 3600);
numminutes = Math.floor(seconds % 31536000 % 86400 % 3600 / 60);
numseconds = seconds % 31536000 % 86400 % 3600 % 60;
nummilli = seconds % 1.0;
res = [];
if (numyears > 0) {
res.push(numyears + " years");
}
if (numdays > 0) {
res.push(numdays + " days");
}
if (numhours > 0) {
res.push(numhours + " hours");
}
if (numminutes > 0) {
res.push(numminutes + " minutes");
}
if (numseconds > 0) {
res.push(numseconds + " seconds");
}
if (nummilli > 0) {
res.push(nummilli + " milliseconds");
}
return [res.slice(0, -1).join(", "), res.slice(-1)[0]].join(res.length > 1 ? " and " : "");
};
It has no period so one can add sentences after it, like here:
perform: function(msg, custom, conn) {
var remTimeLoop;
remTimeLoop = function(time) {
if (time !== +custom[0]) {
msg.reply((secondsToString(time)) + " remaining!");
}
if (time > 15) {
return setTimeout((function() {
return remTimeLoop(time / 2);
}), time / 2);
}
};
// ...
remTimeLoop(+custom[0]);
}
Where custom[0] is the total time to wait for; it will keep dividing the time by 2, warning the time remaining until the timer ends, and stop warning once the time is under 15 seconds.
Below will work for both past and future datetime, also have option to pass locale.
function relativeTime(isoString, locale = "en") {
const timestamp = Date.parse(isoString);
const msPerMinute = 60 * 1000;
const msPerHour = msPerMinute * 60;
const msPerDay = msPerHour * 24;
const msPerMonth = msPerDay * 30;
const msPerYear = msPerDay * 365;
const current = Date.now();
let elapsed = current - timestamp;
const sign = elapsed > 0 ? -1 : 1;
elapsed = Math.abs(elapsed);
const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
if (elapsed < msPerMinute) {
return rtf.format(sign * Math.floor(elapsed / 1000), "seconds");
} else if (elapsed < msPerHour) {
return rtf.format(sign * Math.floor(elapsed / msPerMinute), "minutes");
} else if (elapsed < msPerDay) {
return rtf.format(sign * Math.floor(elapsed / msPerHour), "hours");
} else if (elapsed < msPerMonth) {
return rtf.format(sign * Math.floor(elapsed / msPerDay), "days");
} else if (elapsed < msPerYear) {
return rtf.format(sign * Math.floor(elapsed / msPerMonth), "months");
} else {
return new Date(timestamp).toLocaleString(locale);
}
}
Output:
relativeTime(new Date().toISOString()) //'2021-11-13T18:48:58.243Z'
-> now
relativeTime('2021-11-13T18:48:50.243Z')
-> 8 seconds ago
relativeTime('2021-11-14T18:48:50.243Z')
-> in 23 hours
relativeTime('2021-11-15T18:48:50.243Z')
-> tomorrow
relativeTime('2021-10-15T18:48:50.243Z')
-> 29 days ago
relativeTime('2021-12-15T18:48:50.243Z')
-> next month
This is a solution. Later you can split by ":" and take the values of the array
/**
* Converts milliseconds to human readeable language separated by ":"
* Example: 190980000 --> 2:05:3 --> 2days 5hours 3min
*/
function dhm(t){
var cd = 24 * 60 * 60 * 1000,
ch = 60 * 60 * 1000,
d = Math.floor(t / cd),
h = '0' + Math.floor( (t - d * cd) / ch),
m = '0' + Math.round( (t - d * cd - h * ch) / 60000);
return [d, h.substr(-2), m.substr(-2)].join(':');
}
//Example
var delay = 190980000;
var fullTime = dhm(delay);
console.log(fullTime);
I'm a big fan of objects, so I created this from https://metacpan.org/pod/Time::Seconds
Usage:
var human_readable = new TimeSeconds(986543).pretty(); // 11 days, 10 hours, 2 minutes, 23 seconds
;(function(w) {
var interval = {
second: 1,
minute: 60,
hour: 3600,
day: 86400,
week: 604800,
month: 2629744, // year / 12
year: 31556930 // 365.24225 days
};
var TimeSeconds = function(seconds) { this.val = seconds; };
TimeSeconds.prototype.seconds = function() { return parseInt(this.val); };
TimeSeconds.prototype.minutes = function() { return parseInt(this.val / interval.minute); };
TimeSeconds.prototype.hours = function() { return parseInt(this.val / interval.hour); };
TimeSeconds.prototype.days = function() { return parseInt(this.val / interval.day); };
TimeSeconds.prototype.weeks = function() { return parseInt(this.val / interval.week); };
TimeSeconds.prototype.months = function() { return parseInt(this.val / interval.month); };
TimeSeconds.prototype.years = function() { return parseInt(this.val / interval.year); };
TimeSeconds.prototype.pretty = function(chunks) {
var val = this.val;
var str = [];
if(!chunks) chunks = ['day', 'hour', 'minute', 'second'];
while(chunks.length) {
var i = chunks.shift();
var x = parseInt(val / interval[i]);
if(!x && chunks.length) continue;
val -= interval[i] * x;
str.push(x + ' ' + (x == 1 ? i : i + 's'));
}
return str.join(', ').replace(/^-/, 'minus ');
};
w.TimeSeconds = TimeSeconds;
})(window);
I cleaned up one of the other answers a bit provides nice '10 seconds ago' style strings:
function msago (ms) {
function suffix (number) { return ((number > 1) ? 's' : '') + ' ago'; }
var temp = ms / 1000;
var years = Math.floor(temp / 31536000);
if (years) return years + ' year' + suffix(years);
var days = Math.floor((temp %= 31536000) / 86400);
if (days) return days + ' day' + suffix(days);
var hours = Math.floor((temp %= 86400) / 3600);
if (hours) return hours + ' hour' + suffix(hours);
var minutes = Math.floor((temp %= 3600) / 60);
if (minutes) return minutes + ' minute' + suffix(minutes);
var seconds = Math.floor(temp % 60);
if (seconds) return seconds + ' second' + suffix(seconds);
return 'less then a second ago';
};
function java_seconds_to_readable(seconds)
{
var numhours = Math.floor(seconds / 3600);
var numminutes = Math.floor((seconds / 60) % 60);
var numseconds = seconds % 60;
return numhours + ":" + numminutes + ":" + numseconds;
}
More simple way. You can years and days respectively.
if you use node :
const humanize = require('human-date');
let yesterday = new Date(new Date().setDate(new Date().getDate()-1));
console.log(humanize.relativeTime(yesterday)); //=> 1 day ago
function secondsToTimeString(input) {
let years = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
let ref = [31536000,86400,3600,60,1];
for (let i = 0;i < ref.length;i++) {
let val = ref[i];
while (val <= input) {
input -= val;
if (i === 0) years++;
if (i === 1) days++;
if (i === 2) hours++;
if (i === 3) minutes++;
if (i === 4) seconds++;
}
return {years, days, hours, minutes, seconds};
}

Categories