Reputation: 1511
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?
Upvotes: 95
Views: 185495
Reputation: 15276
Based on https://stackoverflow.com/a/37096512/588759
function secondsToHHMMss(seconds: number) {
if (typeof seconds === 'undefined') throw new Error('seconds is undefined');
const d = Math.abs(seconds);
const h = Math.floor(d / 3600);
const m = Math.floor((d % 3600) / 60);
const s = Math.floor(d % 60);
return [h, m, s].map((n) => String(n).padStart(2, '0')).join(':');
}
Upvotes: 1
Reputation: 746
Using the popular dayjs
function secondsToFormat(seconds: number):string{
// this works until 24 hours
const day = dayjs().startOf('day').add(seconds, 'seconds');
//more than an hour
if(seconds > 3600){
return day.format('HH [hours] mm [minutes] ss [seconds]')
}
else {
return day.format('mm [minutes] ss [seconds]')
}
* this will not work for more than 24 hours (seconds > 86400)
Upvotes: 0
Reputation: 416
function toTime(seconds) {
var date = new Date(null);
date.setSeconds(seconds);
return date.toISOString().substr(11, 8);
}
console.log(toTime(1500)) //'00:25:00'
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);
}
Upvotes: 30
Reputation: 2559
Another option with inline comments:
// Seconds to Days Hours Minutes Seconds function
const sec2DHMS = s => {
// D/Hr/Min from Sec calculation.
// Both Hr and Min timeframes have 60 and D have 24 fractions, so we
// can create one logic for them. We divide Min/Sec on 60 to find out
// whole Hr/Min, then calculate Sec of whole Hr/Min, then calculate
// difference between input Sec and Sec of whole Hr/Min to find out
// fraction of Hr/Min. With D we do same thing, but with 24 divider.
const calc = (v, f) => { const x = Math.trunc(v/f); return [x, v-x*f]; },
[m, sr] = calc(s, 60),
[h, mr] = calc(m, 60),
[d, hr] = calc(h, 24);
return { d, h, m, s, hr, mr, sr };
}
// Test all data
const { d, h, m, s, hr, mr, sr } = sec2DHMS(90061);
console.log(`${d} d, ${hr} hr, ${mr} min, ${sr} sec are whole ${h} hr, or ${m} min, or ${s} sec.`);
// So, if you need only Hr/Min/Sec
console.log(`90061 sec is ${h} hr, ${mr} min, ${sr} sec`);
Upvotes: 0
Reputation: 321
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.
Upvotes: -1
Reputation: 29
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;
}}
Upvotes: 3
Reputation: 98
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;
}
Upvotes: 1
Reputation: 63
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
Upvotes: 3
Reputation: 1
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
Upvotes: 0
Reputation: 57231
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.
Upvotes: 0
Reputation: 183
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
Upvotes: 3
Reputation: 314
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
Upvotes: 4
Reputation: 154
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(' ')
}
Upvotes: 2
Reputation: 1
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"
}
Upvotes: 0
Reputation: 76
@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
Upvotes: 1
Reputation: 41
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;
}
Upvotes: 4
Reputation: 466
Convert to H:M
Number(moment.duration(Number(37320), 'seconds').hours()+'.'+moment.duration(Number(37320),'seconds').minutes())
Upvotes: -2
Reputation: 2490
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;
}
Upvotes: 8
Reputation: 586
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.
Upvotes: 8
Reputation: 823
I'm probably a bit late but you can achieve this kind of things using
myVar = moment(myVar).format('HH:mm');
moment provides A LOT of format for hours / dates etc.
Upvotes: 9
Reputation: 3123
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;
}
You can change the object to
var obj = {
"h": hours + " hours",
"m": minutes + " minutes",
"s": seconds + " seconds"
};
Upvotes: 17
Reputation: 2771
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;
}
Upvotes: 263