displaying hour, minutes and seconds in two digits in Timer - javascript

I am using javascript to show total time elapsed on my website with following code.
It is working correctly....but the problem is when seconds = 0, it's field is empty and when seconds and minutes are between 1 to 9, it is showing one digit.Instead I want to show as follows
if 59 seconds then == 00:00:59 (curretnly showing 59)
if 62 seconds then == 00:01:02 (currently showing 1:2)
if 70 seconds then == 00:01:10 (currently showing 1:10)
if 3640 seconds then == 01:00:40 (currently showing 1:0:40)
I mean fields shown should be fixed with
00:00:00 (hh:mm:ss)
format
javascript code using as follows :
var timeStamp = Date.now(),
sessionStamp = sessionStorage.getItem('ts'),
elapsedTime;
if (!sessionStamp) {
sessionStorage.setItem('ts', timeStamp.toString());
sessionStamp = timeStamp;
} else {
sessionStamp = parseInt(sessionStamp);
}
function increment() {
elapsedTime = Date.now() - sessionStamp;
d1= Math.round(elapsedTime / 1000).toString();
d = Number(d1);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
var hDisplay = h > 0 ? h + (h == 1 ? ":" : ":") : "";
var mDisplay = m > 0 ? m + (m == 1 ? ":" : ":") : "";
var sDisplay = s > 0 ? s + (s == 1 ? "0" : "") : "";
document.getElementById('elapsedTime').textContent = hDisplay + mDisplay + sDisplay;
}
setInterval(increment, 1000);
JSFIDDLE

I have updated the JS fiddle http://jsfiddle.net/03L9pcm2/
Here is what I have changed
var hDisplay = h > 0 ? (h < 10 ? "0" + h + ":" : h + ":") : "00:";
var mDisplay = m > 0 ? (m < 10 ? "0" + m + ":" : m + ":") : "00:";
var sDisplay = s > 0 ? (s < 10 ? "0" + s : s) : "00";

You just needed to format the hours, minutes and seconds slightly differently.
I forked your example here:
http://jsfiddle.net/samrae/xb6n5Lda/6/
var timeStamp = Date.now(),
sessionStamp = sessionStorage.getItem('ts'),
elapsedTime;
if (!sessionStamp) {
sessionStorage.setItem('ts', timeStamp.toString());
sessionStamp = timeStamp;
}
else {
sessionStamp = parseInt(sessionStamp);
}
function increment() {
elapsedTime = Date.now() - sessionStamp;
d1= Math.round(elapsedTime / 1000).toString();
d = Number(d1);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
var hDisplay = h > 0 ? (h < 10 ? "0" : "") + h + ":" : "00:";
var mDisplay = m > 0 ? (m < 10 ? "0" : "") + m + ":" : "00:";
var sDisplay = s > 0 ? (s < 10 ? "0" : "") + s : "00";
document.getElementById('elapsedTime').textContent = hDisplay + mDisplay + sDisplay;
}
setInterval(increment, 1000);
You're on the right track with checking if the seconds are bigger than 0 but you were printing an empty string if they are as apposed to what you need which is "00".
You could separate out the logic for making the hours, mins and seconds into separate functions so that it's easier to follow

This is my own trick. simple and short and stylish:
var hDisplay = (h < 0 ? "00" : ("0"+h).slice(-2)) + ":";
//And others ...

Related

(React) How should i convert seconds passed as props do hours minutes seconds

I have bunch of different values (seconds) passed as props to a child
and i want do convert it so i could render hour,minutes,seconds
Whats the best way to do it?
I think you can find the solution in here or here or here ...
function secondsToHms(d) {
d = Number(d);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
return hDisplay + mDisplay + sDisplay;
}
minutes = this.props.seconds/60;
hours = this.props.seconds/3600;
Have you tried this?

Digital clock in Javascript

The code is for making a digital clock, what's the use of putting a setTimeout function in the showTime function and what is the use of setting both the textcontent and Innertext
function showTime(){
var date = new Date();
var h = date.getHours();// 0 - 23
var m = date.getMinutes(); // 0 - 59
var s = date.getSeconds(); // 0 - 59
var session = "AM";
if(h == 0){
h = 12;
}
if(h > 12){
h = h - 12;
session = "PM";
}
h = (h < 10) ? "0" + h : h;
m = (m < 10) ? "0" + m : m;
s = (s < 10) ? "0" + s : s;
var time = h + ":" + m + ":" + s + " " + session;
document.getElementById("MyClockDisplay").innerText = time;
document.getElementById("MyClockDisplay").textContent = time;
setTimeout(showTime, 1000);
}
showTime();
<div id="MyClockDisplay" class="clock"></div>
You need to call setTimeout at the bottom of showTime so that each call of showTime will queue up the function to run again in 1 second - which, when run, will queue the function again after another second, and so on. Having a function recursively call itself with setTimeout is an alternative to using setInterval.
textContent is generally preferable over innerText - see The poor, misunderstood innerText, though if you're just assigning rather than getting, it doesn't matter much. innerHTML isn't appropriate here because you're assigning text, not HTML markup.
Using setInterval rather than a recursive setTimeout would look like this, accomplishing the exact same thing:
function showTime() {
var date = new Date();
var h = date.getHours(); // 0 - 23
var m = date.getMinutes(); // 0 - 59
var s = date.getSeconds(); // 0 - 59
var session = "AM";
if (h == 0) {
h = 12;
}
if (h > 12) {
h = h - 12;
session = "PM";
}
h = (h < 10) ? "0" + h : h;
m = (m < 10) ? "0" + m : m;
s = (s < 10) ? "0" + s : s;
var time = h + ":" + m + ":" + s + " " + session;
document.getElementById("MyClockDisplay").innerText = time;
document.getElementById("MyClockDisplay").textContent = time;
}
showTime();
setInterval(showTime, 1000);
<div id="MyClockDisplay" class="clock"></div>
The use of the setTimeout is to set next count down for next second.
The use of Innertext is to set the time string to the element .
Innertext and textcontent are the same here.
Maybe you can try SetInterval as below to be more accurate:
function showTime(){
var date = new Date();
var h = date.getHours();// 0 - 23
var m = date.getMinutes(); // 0 - 59
var s = date.getSeconds(); // 0 - 59
var session = "AM";
if(h == 0){
h = 12;
}
if(h > 12){
h = h - 12;
session = "PM";
}
h = (h < 10) ? "0" + h : h;
m = (m < 10) ? "0" + m : m;
s = (s < 10) ? "0" + s : s;
var time = h + ":" + m + ":" + s + " " + session;
document.getElementById("MyClockDisplay").innerText = time;
document.getElementById("MyClockDisplay").textContent = time;
}
showTime();
setInterval(showTime, 1000);

How to convert seconds to minutes and hours in javascript

I have a count of seconds stored in variable seconds. I want to convert for example 1439 seconds to 23 minutes and 59 seconds. And if the time is greater than 1 hour (for example 9432 seconds), to 2 hours, 37 minutes and 12 seconds.
How can I achieve this?
I'm thinking of:
var sec, min, hour;
if(seconds<3600){
var a = Math.floor(seconds/60); //minutes
var b = seconds%60; //seconds
if (b!=1){
sec = "seconds";
}else{
sec = "second";
}
if(a!=1){
min = "minutes";
}else{
min = "minute";
}
$('span').text("You have played "+a+" "+min+" and "+b+" "+sec+".");
}else{
var a = Math.floor(seconds/3600); //hours
var x = seconds%3600;
var b = Math.floor(x/60); //minutes
var c = seconds%60; //seconds
if (c!=1){
sec = "seconds";
}else{
sec = "second";
}
if(b!=1){
min = "minutes";
}else{
min = "minute";
}
if(c!=1){
hour = "hours";
}else{
hour = "hour";
}
$('span').text("You have played "+a+" "+hour+", "+b+" "+min+" and "+c+" "+sec+".");
}
But that's a lot of code, and it has to be calculated each second. How can I shrink this up?
I think you would find this solution very helpful.
You modify the display format to fit your needs with something like this -
function secondsToHms(d) {
d = Number(d);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
return hDisplay + mDisplay + sDisplay;
}
The builtin JavaScript Date object can simplify the required code
toTime(seconds) {
var date = new Date(null);
date.setSeconds(seconds);
return date.toISOString().substr(11, 8);
}
You can try this, i have used this successfully in the past
You should be able to add the minutes and seconds on easily
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);
var obj = {
"h": hours,
"m": minutes,
"s": seconds
};
return obj;
}
Fiddle
You can change the object to
var obj = {
"h": hours + " hours",
"m": minutes + " minutes",
"s": seconds + " seconds"
};
I'm probably a bit late but you can achieve this kind of things using
https://momentjs.com/
myVar = moment(myVar).format('HH:mm');
moment provides A LOT of format for hours / dates etc.
A low fat way to do this is:
function seconds_to_days_hours_mins_secs_str(seconds)
{ // day, h, m and s
var days = Math.floor(seconds / (24*60*60));
seconds -= days * (24*60*60);
var hours = Math.floor(seconds / (60*60));
seconds -= hours * (60*60);
var minutes = Math.floor(seconds / (60));
seconds -= minutes * (60);
return ((0<days)?(days+" day, "):"")+hours+"h, "+minutes+"m and "+seconds+"s";
}
Thus
> seconds_to_days_hours_mins_secs_str(9432+60*60*24)
'1 days, 2h, 37m and 12s'
This is easy to understand and extend as needed.
Try this, Convert SEC to H:M:S.
function convertTime(sec) {
var hours = Math.floor(sec/3600);
(hours >= 1) ? sec = sec - (hours*3600) : hours = '00';
var min = Math.floor(sec/60);
(min >= 1) ? sec = sec - (min*60) : min = '00';
(sec < 1) ? sec='00' : void 0;
(min.toString().length == 1) ? min = '0'+min : void 0;
(sec.toString().length == 1) ? sec = '0'+sec : void 0;
return hours+':'+min+':'+sec;
}
I found Wilson Lee's and Brian's code super useful! Here is how I adapted their code:
function formatTime(serverTimeinSeconds, elementId)
{ /* This converts seconds into days, hours, minutes and seconds timestring.
Requires JQuery if elementId argument is provided */
seconds = Math.floor(Number(serverTimeinSeconds));
days = Math.floor(seconds / (24*60*60));
seconds -= Math.floor(days * (24*60*60));
hours = Math.floor(seconds / (60*60));
seconds -= Math.floor(hours * (60*60));
minutes = Math.floor(seconds / (60));
seconds -= Math.floor(minutes * (60));
dDisplay = days > 0 ? days + (days == 1 ? ' day, ' : ' days, ') : '';
hDisplay = hours > 0 ? hours + (hours == 1 ? ' hour, ' : ' hours, ') : '';
mDisplay = minutes > 0 ? minutes + (minutes == 1 ? ' minute, ' : ' minutes, ') : '';
sDisplay = seconds > 0 ? seconds + (seconds == 1 ? ' second' : ' seconds') : '';
if (elementId != null) {
if (serverTimeinSeconds < 60) {
$(elementId).css('font-size', '15px');
$(elementId).html(sDisplay);
}
if (serverTimeinSeconds >= 60 && serverTimeinSeconds < 3600) {
$(elementId).css('font-size', '15px');
$(elementId).html(mDisplay + sDisplay);
}
if (serverTimeinSeconds >= 3600 && serverTimeinSeconds < 86400) {
$(elementId).css('font-size', '12px');
$(elementId).html(hDisplay + mDisplay + sDisplay);
}
if (serverTimeinSeconds >= 86400 && serverTimeinSeconds !== Infinity) {
$(elementId).css('font-size', '8px');
$(elementId).html(dDisplay + hDisplay + mDisplay + sDisplay);
}
}
return dDisplay + hDisplay + mDisplay + sDisplay;
}
Please install moment js after that import it,
import moment from 'moment'
let dateForm = (arg) => {
return moment.unix(arg).utc().format('H [hours,] m [minutes and] s [seconds]');
}
console.log(dateForm(11));
// 0 hours, 0 minutes and 11 seconds
console.log(dateForm(16060));
// 1 hours, 0 minutes and 0 seconds
const formatter = (seconds = 0) => {
const d = Number(secondsAmount);
const h = Math.floor(d / 3600);
const m = Math.floor((d % 3600) / 60);
const s = Math.floor((d % 3600) % 60);
const hDisplay = h > 0 ? `${h.toString().length > 1 ? `${h}` : `${0}${h}`}` : '00';
const mDisplay = m > 0 ? `${m.toString().length > 1 ? `${m}` : `${0}${m}`}` : '00';
const sDisplay = s > 0 ? `${s.toString().length > 1 ? `${s}` : `${0}${s}`}` : '00';
return `${hDisplay}:${mDisplay}:${sDisplay}`;
};
Will return this format human readable format 00:00:00
Built off R4nc1d's answer:
function secondsToTime(secs){
var h = Math.floor(secs / (60 * 60));
var divisor_for_minutes = secs % (60 * 60);
var m = Math.floor(divisor_for_minutes / 60);
var divisor_for_seconds = divisor_for_minutes % 60;
var s = Math.ceil(divisor_for_seconds);
return `${h?`${h}:`:""}${m?`${m}:${s}`:`${s}s`}`
}
This will return a human readable answer which looks like this. I used this for displaying the length of music tracks
time = secondsToTime(5)
console.log(time) // 5s
time = secondsToTime(50)
console.log(time) // 50s
time = secondsToTime(500)
console.log(time) // 8:20
time = secondsToTime(5000)
console.log(time) // 1:23:20
#pkerckhove has already mentioned moment as a great library to work with dates and times, and you can also use moment to directly format the seconds into OP's desired format, i.e.:
import moment from 'moment'
const myVar = 1439
console.log(
moment.unix(myVar).utc().format('H [hours,] m [minutes and] s [seconds]')
)
Will result in: 0 hours, 23 minutes and 59 seconds and,
import moment from 'moment'
const myVar = 9432
console.log(
moment.unix(myVar).utc().format('H [hours,] m [minutes and] s [seconds]')
)
Will result in: 2 hours, 37 minutes and 12 seconds
One way of doing it:
const formatDuration = totalSeconds => {
const hours = Math.floor(totalSeconds / 3600)
const minutes = Math.floor((totalSeconds % 3600) / 60)
const seconds = totalSeconds - hours * 3600 - minutes * 60
return [`${hours}h`, `${minutes}m`, `${seconds}s`]
.filter(item => item[0] !== '0')
.join(' ')
}
This method also works with a negative amount of time:
function CalculateTime(sec){
if(sec >= 0){
var h = Math.floor(sec / 3600);
var m = Math.floor(sec % 3600 / 60);
var s = Math.floor(sec % 3600 % 60);
}
else{
var h = Math.ceil(sec / 3600);
var m = Math.ceil(sec % 3600 / 60);
var s = Math.ceil(sec % 3600 % 60);
}
var hDisplay = h !== 0 ? h + (h == 1 ? " hour, " : " hours") + (m != 0 || s > 0 ? ", ":"") : "";
var mDisplay = m !== 0 ? m + (m == 1 ? " minute, " : " minutes") + (s != 0 ? " ":""): "";
var sDisplay = s !== 0 ? s + (s == 1 ? " second" : " seconds") : "";
return hDisplay + mDisplay + sDisplay;
}
for having the result with the time format " 00:00:00 " I added some changes to it.
function secondsToHms(seconds) {
let d = Number(seconds);
if(d <= 0){
return '00:00:00'
}else{
let h = Math.floor(d / 3600);
let m = Math.floor(d % 3600 / 60);
let s = Math.floor(d % 3600 % 60);
let hDisplay = h <= 9 ? '0'+ h+':' : h+ ":";
let mDisplay = m <= 9 ? '0'+ m+':' : m+ ":";
let sDisplay = s <= 9 ? '0'+ s : s;
return hDisplay + mDisplay + sDisplay;
}}
Try this :D
secondsToHms(d) {
d = Number(d);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
var hDisplay = h > 0 ? h + (h == 1 ? "" : "") : "";
var mDisplay = m > 0 ? m + (m == 1 ? "" : "") : "";
var sDisplay = s > 0 ? s + (s == 1 ? "" : "") : "";
if (hDisplay != "") {
return (hDisplay.length > 1 ? hDisplay : '0' + hDisplay) + ":" + (mDisplay.length > 1 ? mDisplay : '0' + mDisplay) + ":" + (sDisplay.length > 1 ? sDisplay : '0' + sDisplay);
}
else if (mDisplay != "") {
return (mDisplay.length > 1 ? mDisplay : '0' + mDisplay) + ":" + (sDisplay.length > 1 ? sDisplay : '0' + sDisplay);
}
else if (sDisplay != "") {
return "00:" + (sDisplay.length > 1 ? sDisplay : '0' + sDisplay);
}
return "00:00"
}
Using the popular date-fns library
import { format, setSeconds, startOfDay } from 'date-fns'
export const hourMinSec = (secs: number, showHour = false): string => {
const tmpDate: Date = startOfDay(new Date())
const date: Date = setSeconds(tmpDate, secs)
const hour: number = date.getHours()
const hasHour: boolean = !!hour
if (hasHour && !showHour) console.warn('hourMinSec is hiding a non zero hour')
const strFormat: string = showHour ? 'H:mm:ss' : 'm:ss'
return format(date, strFormat)
}
OR the same code with a more functional approach (adding lodash flow in the mix)
import { setSeconds, startOfDay } from 'date-fns/fp'
import { format } from 'date-fns'
import { flow } from 'lodash-es'
export const hourMinSec = (secs: number, showHour = false): string => {
const date: Date = flow(startOfDay, setSeconds(secs))(new Date())
const hour: number = date.getHours()
const hasHour: boolean = !!hour
if (hasHour && !showHour) console.warn('hourMinSec is hiding a non zero hour')
const strFormat: string = showHour ? 'H:mm:ss' : 'm:ss'
return format(date, strFormat)
}
Usage:
hourMinSec(100) // 1:40
hourMinSec(3700) // 1:40 // will warn in logs that a non zero hour is hidden
hourMinSec(100, true) // 0:01:40
hourMinSec(3700, true) // 1:01:40
This met my needs but you could adapt this by changing the showHour = false parameter to be a strFormat = 'm:ss' parameter instead to support more flexible formatting.
const minutes = Math.floor(duration / 60);
const seconds = Math.floor(duration - minutes * 60);
const time = `${minutes < 10 ? `0${minutes}` : minutes}
:${seconds < 10 ? `0${seconds}` : seconds}`; // result: 02:23
useCountDown Hook
// useCountDown.js
import { useEffect, useState } from "react"
const useCountDown = (minutes) => {
const [seconds, setSeconds] = useState(minutes * 60)
useEffect(() => {
const interval = setInterval(() => {
setSeconds(seconds - 1)
}, 1000)
return () => clearInterval(interval)
}, [seconds])
return getReturnValues2(seconds)
}
const getReturnValues2 = (countDown) => {
const minutes = Math.floor(countDown / 60)
const seconds = countDown % 60
return `${padTo2Digits(minutes)}:${padTo2Digits(seconds)}`
}
function padTo2Digits(num) {
return num.toString().padStart(2, "0")
}
export default useCountDown
How to use?
//React Component
import useCountDown from '../hooks/useCountDown'
function App() {
const countDown = useCountDown(5) // 5 Minutes
return (
<h1> {countDown} </h1> // MM:SS
)
}
You can tweak as per your needs.
Convert to H:M
Number(moment.duration(Number(37320), 'seconds').hours()+'.'+moment.duration(Number(37320),'seconds').minutes())

Convert seconds to days, hours, minutes and seconds

I have a Javascript timing event with an infinite loop with a stop button.
It will display numbers when start button is click.Now I want this numbers converted to something like 4 hours, 3 minutes , 50 seconds
var c = 0;
var t;
var timer_is_on = 0;
function timedCount() {
document.getElementById('txt').value = c;
c = c + 1;
t = setTimeout(function() {
timedCount()
}, 1000);
}
function doTimer() {
if (!timer_is_on) {
timer_is_on = 1;
timedCount();
}
}
function stopCount() {
clearTimeout(t);
timer_is_on = 0;
}
$(".start").on("click", function() {
//var start = $.now();
//alert(start);
//console.log(start);
doTimer();
$(".end").show();
$(".hide_div").show();
});
$(".end").on("click", function() {
stopCount();
});
.hide_div {
display: none;
}
.end {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="start">Start</p>
<p class="end">End</p>
<p class="hide_div">
<input type="text" id="txt" />//display numbers eg 12345
</p>
How to convert numbers like 123456 to 1 day, 4 hours, 40 min, 45 seconds?
I suggest doing this way!:
function secondsToDhms(seconds) {
seconds = Number(seconds);
var d = Math.floor(seconds / (3600*24));
var h = Math.floor(seconds % (3600*24) / 3600);
var m = Math.floor(seconds % 3600 / 60);
var s = Math.floor(seconds % 60);
var dDisplay = d > 0 ? d + (d == 1 ? " day, " : " days, ") : "";
var hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
var mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
var sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
return dDisplay + hDisplay + mDisplay + sDisplay;
}
Use Math like this way, Second param in parseInt is for base, which is optional
var seconds = parseInt(123456, 10);
var days = Math.floor(seconds / (3600*24));
seconds -= days*3600*24;
var hrs = Math.floor(seconds / 3600);
seconds -= hrs*3600;
var mnts = Math.floor(seconds / 60);
seconds -= mnts*60;
console.log(days+" days, "+hrs+" Hrs, "+mnts+" Minutes, "+seconds+" Seconds");
Your given seconds 123456 would be 1 days, 10 Hrs, 17 Minutes, 36 Seconds not 1 days, 4 Hrs, 40 Minutes, 45 Seconds
function countdown(s) {
const d = Math.floor(s / (3600 * 24));
s -= d * 3600 * 24;
const h = Math.floor(s / 3600);
s -= h * 3600;
const m = Math.floor(s / 60);
s -= m * 60;
const tmp = [];
(d) && tmp.push(d + 'd');
(d || h) && tmp.push(h + 'h');
(d || h || m) && tmp.push(m + 'm');
tmp.push(s + 's');
return tmp.join(' ');
}
// countdown(3546544) -> 41d 1h 9m 4s
// countdown(436654) -> 5d 1h 17m 34s
// countdown(3601) -> 1h 0m 1s
// countdown(121) -> 2m 1s
My solution with map() and reduce():
const intervalToLevels = (interval, levels) => {
const cbFun = (d, c) => {
let bb = d[1] % c[0],
aa = (d[1] - bb) / c[0];
aa = aa > 0 ? aa + c[1] : '';
return [d[0] + aa, bb];
};
let rslt = levels.scale.map((d, i, a) => a.slice(i).reduce((d, c) => d * c))
.map((d, i) => ([d, levels.units[i]]))
.reduce(cbFun, ['', interval]);
return rslt[0];
};
const TimeLevels = {
scale: [24, 60, 60, 1],
units: ['d ', 'h ', 'm ', 's ']
};
const secondsToString = interval => intervalToLevels(interval, TimeLevels);
If you call secondsToString(123456), you can get "1d 10h 17m 36s "
Here is my solution, a simple function that will round to the nearest second!
var returnElapsedTime = function(epoch) {
//We are assuming that the epoch is in seconds
var hours = epoch / 3600,
minutes = (hours % 1) * 60,
seconds = (minutes % 1) * 60;
return Math.floor(hours) + " hours, " + Math.floor(minutes) + " minutes, " + Math.round(seconds) + " seconds";
}
Came up with my own variation to some of the solutions suggested in this thread.
if (!Number.prototype.secondsToDHM) {
Number.prototype.secondsToDHM = function() {
const secsPerDay = 86400;
const secsPerHour = 3600;
const secsPerMinute = 60;
var seconds = Math.abs(this);
var minus = (this < 0) ? '-' : '';
var days = Math.floor(seconds / secsPerDay);
seconds = (seconds % secsPerDay);
var hours = Math.floor(seconds / secsPerHour);
seconds = (seconds % secsPerHour);
var minutes = Math.floor(seconds / secsPerMinute);
seconds = (seconds % secsPerMinute);
var sDays = new String(days).padStart(1, '0');
var sHours = new String(hours).padStart(2, '0');
var sMinutes = new String(minutes).padStart(2, '0');
return `${minus}${sDays}D ${sHours}:${sMinutes}`;
}
}
var a = new Number(50000).secondsToDHM();
var b = new Number(100000).secondsToDHM();
var c = new Number(200000).secondsToDHM();
var d = new Number(400000).secondsToDHM();
console.log(a);
console.log(b);
console.log(c);
console.log(d);
This answer builds upon on Andris' approach to this question, but it doesn't have trailing commas if lesser units are not present.
It also borrows from this answer dealing with joining array values only if truthy:
https://stackoverflow.com/a/19903063
I'm not a javascript god and it's probably horribly over-engineered, but hopefully readable and correct!
function sformat(s) {
// create array of day, hour, minute and second values
var fm = [
Math.floor(s / (3600 * 24)),
Math.floor(s % (3600 * 24) / 3600),
Math.floor(s % 3600 / 60),
Math.floor(s % 60)
];
// map over array
return $.map(fm, function(v, i) {
// if a truthy value
if (Boolean(v)) {
// add the relevant value suffix
if (i === 0) {
v = plural(v, "day");
} else if (i === 1) {
v = plural(v, "hour");
} else if (i === 2) {
v = plural(v, "minute");
} else if (i === 3) {
v = plural(v, "second");
}
return v;
}
}).join(', ');
}
function plural(value, unit) {
if (value === 1) {
return value + " " + unit;
} else if (value > 1) {
return value + " " + unit + "s";
}
}
console.log(sformat(60)); // 1 minute
console.log(sformat(3600)); // 1 hour
console.log(sformat(86400)); // 1 day
console.log(sformat(8991)); // 2 hours, 29 minutes, 51 seconds
If you needed to convey the duration more 'casually' in words, you could also do something like:
var remaining_duration = sformat(117);
// if a value is returned, add some prefix and suffix
if (remaining_duration !== "") {
remaining_duration = "about " + remaining_duration + " left";
}
$(".remaining_duration").text(remaining_duration);
// returns 'about 1 minute, 57 seconds left'
I further tweaked the code by Svetoslav as follows:
function convertSecondsToReadableString(seconds) {
seconds = seconds || 0;
seconds = Number(seconds);
seconds = Math.abs(seconds);
const d = Math.floor(seconds / (3600 * 24));
const h = Math.floor(seconds % (3600 * 24) / 3600);
const m = Math.floor(seconds % 3600 / 60);
const s = Math.floor(seconds % 60);
const parts = [];
if (d > 0) {
parts.push(d + ' day' + (d > 1 ? 's' : ''));
}
if (h > 0) {
parts.push(h + ' hour' + (h > 1 ? 's' : ''));
}
if (m > 0) {
parts.push(m + ' minute' + (m > 1 ? 's' : ''));
}
if (s > 0) {
parts.push(s + ' second' + (s > 1 ? 's' : ''));
}
return parts.join(', ');
}
Short answer:
var s = (Math.floor(123456/86400) + ":" + (new Date(123456 * 1000)).toISOString().substr(11, 8)).split(":");
console.log(`${s[0]} days, ${s[1]} hours, ${s[2]} minutes, ${s[3]} seconds` )
Edit:
Let me break it down in parts :
Math.floor(123456/86400)
86400 is the the total seconds in a day (60 seconds * 60 minutes * 24 hours). Dividing the inputted seconds by this value gives us number of days. We just need the whole part so we use Math.floor because the fractional piece is handled by this part:
(new Date(123456 * 1000)).toISOString().substr(11, 8)
the explanation can be found here:
Convert seconds to HH-MM-SS with JavaScript?
It just outputs hh:mm:ss, no days. So the first part and this part is a perfect combination
We concatenate using a colon (:) as a separator. The string looks like this:
'1:10:17:36'
We split it into an array with .split(":");. Then finally, we format the elements of the array for the desired output.
I've tweaked the code that Andris posted https://stackoverflow.com/users/3564943/andris
// https://stackoverflow.com/questions/36098913/convert-seconds-to-days-hours-minutes-and-seconds
function app_ste_36098913_countdown_seconds_to_hr(seconds) {
seconds = seconds || 0;
seconds = Number(seconds);
seconds = Math.abs(seconds);
var d = Math.floor(seconds / (3600*24));
var h = Math.floor(seconds % (3600*24) / 3600);
var m = Math.floor(seconds % 3600 / 60);
var s = Math.floor(seconds % 60);
var parts = new Array();
if (d > 0) {
var dDisplay = d > 0 ? d + ' ' + (d == 1 ? "day" : "days") : "";
parts.push(dDisplay);
}
if (h > 0) {
var hDisplay = h > 0 ? h + ' ' + (h == 1 ? "hour" : "hours") : "";
parts.push(hDisplay)
}
if (m > 0) {
var mDisplay = m > 0 ? m + ' ' + (m == 1 ? "minute" : "minutes") : "";
parts.push(mDisplay)
}
if (s > 0) {
var sDisplay = s > 0 ? s + ' ' + (s == 1 ? "second" : "seconds") : "";
parts.push(sDisplay)
}
return parts.join(', ', parts);
}
You will probably find using epoch timestamps more straightforward: As detailed in Convert a Unix timestamp to time in JavaScript, the basic method is like so:
<script>
// Create a new JavaScript Date object based on the timestamp
// multiplied by 1000 so that the argument is in milliseconds, not seconds.
var date1 = new Date();
alert ('easy trick to waste a few seconds...' + date1);
// var date = date2 - date1;
// Hours part from the timestamp
var hours1 = date1.getHours();
// Minutes part from the timestamp
var minutes1 = "0" + date1.getMinutes();
// Seconds part from the timestamp
var seconds1 = "0" + date1.getSeconds();
var date2 = new Date();
// Hours part from the timestamp
var hours2 = date2.getHours();
// Minutes part from the timestamp
var minutes2 = "0" + date2.getMinutes();
// Seconds part from the timestamp
var seconds2 = "0" + date2.getSeconds();
// Will display time in 10:30:23 format
// var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
var elapsedHrs = hours2 - hours1;
var elapsedMin = minutes2.substr(-2) -minutes1.substr(-2);
var elapsedSec = seconds2.substr(-2) - seconds1.substr(-2);
var elapsedTime = elapsedHrs + ' hours, ' + elapsedMin + ' minutes, ' + elapsedSec + ' seconds';
alert ('time between timestamps: ' + elapsedTime);
</script>
Be warned that this script needs some work since for now it will give negative values for things like date1 = 12:00:00 and date2 = 12:00:05, but I'll leave that to you fo now.
You should rewrite your code to take a timestamp ( var x = new Date(); ) at the start of your timer and one whenever you are done/want to check elapsed time, and subtract the two before parsing out elapsed seconds, minutes, hours etc as required.
This is my take at the question, even if it is an old topic.
You can use a loop to compute everything for you :
function time_remaining(date1, date2) {
let seconds = (date2 - date1) / 1000
let units = ["years", "days", "h", "min", "s"]
let limit_units = [365, 24, 60, 60, 1]
const reducer = (accumulator, curr) => accumulator * curr;
let time = []
for (let i = 0; i < units.length; i++) {
let divisor = limit_units.slice(i).reduce(reducer)
let value = Math.floor(seconds / divisor)
seconds = seconds - value * divisor
time.push(value)
}
return clean_time(time, units)
}
// at this point, you have your answer. However,
// we can improve the result by removing all none
// significative null units (i.e, if your countdown is
// only about hours, minutes and seconds, it is not
// going to include years and days.)
function clean_time(time, units) {
time = time.reverse()
while (time[time.length - 1] == 0) {
time.pop()
}
return [time.reverse(), units.slice(-time.length)]
}
let date1 = Date.parse("2023-07-09T17:50:33")
console.log(time_remaining(Date.now(), date1))

Javascript Seconds to HMS not working with float points

i want to convert seconds to Hour seconds and minutes, i have a function to do this which is working fine for Numbers, when we call the same function with floating points which i consider as milliseconds it all ways returning "0.00"
function secondsToHms(d) {
d = Number(d);
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.floor(d % 3600 % 60);
return ((h > 0 ? h + ":" + (m < 10 ? "0" : "") : "") + m + ":" + (s < 10 ? "0" : "") + s);
}
Fiddle : Fiddle
i don't know why the floating points are not working with this function

Categories