How to sum time string in an array? - javascript

Suppose, I've an array of different time string.
let a: any = ["7:20", "5:50", "6:30"];
I want to sum up these HH:mm time strings. I am building up an app using Ionic 4 (Angular). I have already used momentjs for these. But, unfortunately yet I can't find any solution.
Update:
Expected Result:
7:20 + 5:50 + 6:30 = 19:40 (HH:33)

You can treat time as moment durations that can be summed up:
const any = ['7:20', '7:52', '5:03', '1:01', '9:02', '6:00'];
const sum = any.reduce((acc, time) => acc.add(moment.duration(time)), moment.duration());
console.log([Math.floor(sum.asHours()), sum.minutes()].join(':'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>

You could use reduce method by passing a callback function.
let arr= ["7:20", "5:50", "6:30"];
toSeconds = (str) => {
str = str.split(':');
return (+str[0]) * 60 + (+str[1]);
}
toHHss = (seconds) => {
let minutes = parseInt(seconds/60);
seconds = seconds - minutes*60;
return minutes + ':' + seconds;
}
let result = arr.reduce((r,elem) => r + toSeconds(elem), 0);
console.log(toHHss(result));

A POJS solution can be very simple:
/* Add array of time strings in H:mm format
** #param {Array<string>} timeArray - Array of H:mm
** #returns {string} - sum of times in H:mm format
*/
function addTimes(timeArray) {
let mins = timeArray.reduce((acc, time) => {
let [h, m] = time.split(':');
acc += h*60 + m*1;
return acc;
}, 0);
return (mins/60|0) + ':' + ('0'+(mins%60)).slice(-2);
}
// Example
console.log(addTimes(["7:20", "5:03", "6:42"]));

Vanilla Javascript implementation:
const secondsToHm = s => ({
hours: ((s - s % 3600) / 3600) % 60,
minutes: ((s - s % 60) / 60) % 60,
})
let a = ["7:20", "5:50", "6:30"];
let total = 0;
for(let i = 0; i < a.length; i++){
const aSlice = a[i].split(':');
const aSeconds = (+aSlice[0]) * 60 * 60 + (+aSlice[1]) * 60;
total += aSeconds
}
console.log(`${secondsToHm(total).hours}:${secondsToHm(total).minutes}`);

You can use moment.duration() to get the number of milliseconds for each time string in the array, and add them.
a.reduce((acc, t) => acc.add(moment.duration(t)), moment.duration())

Related

I want to add 15 minutes slot to each StartTime in a loop and store in array of objects

const createTimeSlots=(fromTime,toTime)=>{
I want to add 15 minutes slot to each StartTime in a loop and store in array of objects.
Assuming the inputs are in timestamp, add 15 mins equivalent of timestamps and push that timestamp(or push mins/hrs etc.). Here's the code example where start time is current timestamp and endtime is current + 3hrs in timestamp.
function createSlots(start, end) {
let slots = [];
const mins = 15 * 60 * 1000; // 15 mins
const date = (dt) => new Date(dt);
while (start <= end) {
start += mins;
// only mins
//slots.push(date(start).getMinutes());
// hrs + mins
slots.push(`${date(start).getHours()}:${date(start).getMinutes()}`);
}
return slots;
}
var slots = createSlots(Date.now(), Date.now() + 3 * 3600 * 1000); // from (now) to (now + 3hrs)
console.log("slots : ", slots);
Let's assume inputs are valid date-time format.
This solution will work across dates, let's say you give the start time today and end time tomorrow then also it will work without any issue.
const createTimeSlots = (fromTime, toTime, slotLength =15*60) => {
let slotStart = new Date(fromTime).valueOf();
let slotEnd = new Date(fromTime).valueOf() + slotLength * 1000;
let endEpoch = new Date(toTime).valueOf();
let ob = [];
for (slotEnd; slotEnd <= endEpoch; slotEnd = slotEnd + slotLength * 1000) {
ob.push({
'from': formatDate(slotStart),
'to': formatDate(slotEnd)
});
slotStart = slotEnd;
}
return ob;
}
function formatDate(epoch) {
let d = new Date(epoch);
let month = String((d.getMonth() + 1)).padStart(2, '0');
let day = String((d.getDate())).padStart(2, '0');
let hours = String((d.getHours())).padStart(2, '0');
let mins = String((d.getMinutes())).padStart(2, '0');
return `${d.getFullYear()}-${month}-${day} ${hours}:${mins}`;
}
const from = "2022-05-25 23:00";
const to = "2022-05-26 01:00";
const slotLength = 15 * 60; //seconds
var r = createTimeSlots(from, to, slotLength );
console.log(r);

Turning an input (amount of seconds) into an HH:MM:SS format for from API [duplicate]

How can I convert seconds to an HH-MM-SS string using JavaScript?
You can manage to do this without any external JavaScript library with the help of JavaScript Date method like following:
const date = new Date(null);
date.setSeconds(SECONDS); // specify value for SECONDS here
const result = date.toISOString().slice(11, 19);
Or, as per #Frank's comment; a one liner:
new Date(SECONDS * 1000).toISOString().slice(11, 19);
Updated (2020):
Please use #Frank's one line solution:
new Date(SECONDS * 1000).toISOString().substring(11, 16)
If SECONDS<3600 and if you want to show only MM:SS then use below code:
new Date(SECONDS * 1000).toISOString().substring(14, 19)
It is by far the best solution.
Old answer:
Use the Moment.js library.
I don't think any built-in feature of the standard Date object will do this for you in a way that's more convenient than just doing the math yourself.
hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
minutes = Math.floor(totalSeconds / 60);
seconds = totalSeconds % 60;
Example:
let totalSeconds = 28565;
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60;
console.log("hours: " + hours);
console.log("minutes: " + minutes);
console.log("seconds: " + seconds);
// If you want strings with leading zeroes:
minutes = String(minutes).padStart(2, "0");
hours = String(hours).padStart(2, "0");
seconds = String(seconds).padStart(2, "0");
console.log(hours + ":" + minutes + ":" + seconds);
I know this is kinda old, but...
ES2015:
var toHHMMSS = (secs) => {
var sec_num = parseInt(secs, 10)
var hours = Math.floor(sec_num / 3600)
var minutes = Math.floor(sec_num / 60) % 60
var seconds = sec_num % 60
return [hours,minutes,seconds]
.map(v => v < 10 ? "0" + v : v)
.filter((v,i) => v !== "00" || i > 0)
.join(":")
}
It will output:
toHHMMSS(129600) // 36:00:00
toHHMMSS(13545) // 03:45:45
toHHMMSS(180) // 03:00
toHHMMSS(18) // 00:18
As Cleiton pointed out in his answer, moment.js can be used for this:
moment().startOf('day')
.seconds(15457)
.format('H:mm:ss');
Here's a simple function for converting times that might help
function formatSeconds(seconds) {
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
This does the trick:
function secondstotime(secs)
{
var t = new Date(1970,0,1);
t.setSeconds(secs);
var s = t.toTimeString().substr(0,8);
if(secs > 86399)
s = Math.floor((t - Date.parse("1/1/70")) / 3600000) + s.substr(2);
return s;
}
(Sourced from here)
var timeInSec = "661"; //even it can be string
String.prototype.toHHMMSS = function () {
/* extend the String by using prototypical inheritance */
var seconds = parseInt(this, 10); // don't forget the second param
var hours = Math.floor(seconds / 3600);
var minutes = Math.floor((seconds - (hours * 3600)) / 60);
seconds = seconds - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
var time = hours+':'+minutes+':'+seconds;
return time;
}
alert("5678".toHHMMSS()); // "01:34:38"
console.log(timeInSec.toHHMMSS()); //"00:11:01"
we can make this function lot shorter and crisp but that decreases the readability, so we will write it as simple as possible and as stable as possible.
or you can check this working here:
Try this:
function toTimeString(seconds) {
return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
}
I think the most general (and cryptic) solution could be this
function hms(seconds) {
return [3600, 60]
.reduceRight(
(pipeline, breakpoint) => remainder =>
[Math.floor(remainder / breakpoint)].concat(pipeline(remainder % breakpoint)),
r => [r]
)(seconds)
.map(amount => amount.toString().padStart(2, '0'))
.join('-');
}
Or to copy & paste the shortest version
function hms(seconds) {
return [3600, 60]
.reduceRight(
(p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
r => [r]
)(seconds)
.map(a => a.toString().padStart(2, '0'))
.join('-');
}
Some example outputs:
> hms(0)
< "00-00-00"
> hms(5)
< "00-00-05"
> hms(60)
< "00-01-00"
> hms(3785)
< "01-03-05"
> hms(37850)
< "10-30-50"
> hms(378500)
< "105-08-20"
How it works
Algorithm
To get hours you divide total seconds by 3600 and floor it.
To get minutes you divide remainder by 60 and floor it.
To get seconds you just use the remainder.
It would also be nice to keep individual amounts in an array for easier formatting.
For example given the input of 3785s the output should be [1, 3, 5], that is 1 hour, 3 minutes and 5 seconds.
Creating pipeline
Naming the 3600 and 60 constants "breakpoints" you can write this algorithm into function as this
function divideAndAppend(remainder, breakpoint, callback) {
return [Math.floor(remainder / breakpoint)].concat(callback(remainder % breakpoint));
}
It returns an array where first item is the amount for given breakpoint and the rest of the array is given by the callback.
Reusing the divideAndAppend in callback function will give you a pipeline of composed divideAndAppend functions. Each one of these
computes amount per given breakpoint and append it to the array making your desired output.
Then you also need the "final" callback that ends this pipeline. In another words you used all breakpoints and now you have only the remainder.
Since you have already the answer at 3) you should use some sort of identity function, in this case remainder => [remainder].
You can now write the pipeline like this
let pipeline = r3 => divideAndAppend(
r3,
3600,
r2 => divideAndAppend(
r2,
60,
r1 => [r1]));
> pipeline(3785)
< [1, 3, 5]
Cool right?
Generalizing using for-loop
Now you can generalize with a variable amount of breakpoints and create a for-loop that will compose individial divideAndAppend functions into
the pipeline.
You start with the identity function r1 => [r1], then use the 60 breakpoint and finally use the 3600 breakpoint.
let breakpoints = [60, 3600];
let pipeline = r => [r];
for (const b of breakpoints) {
const previousPipeline = pipeline;
pipeline = r => divideAndAppend(r, b, previousPipeline);
}
> pipeline(3785)
< [1, 3, 5]
Using Array.prototype.reduce()
Now you can rewrite this for-loop into reducer for shorter and more functional code. In other words rewrite function composition into the reducer.
let pipeline = [60, 3600].reduce(
(ppln, b) => r => divideAndAppend(r, b, ppln),
r => [r]
);
> pipeline(3785)
< [1, 3, 5]
The accumulator ppln is the pipeline and you are composing it using the previous version of it. The initial pipeline is r => [r].
You can now inline the function divideAndAppend and use Array.prototype.reduceRight which is the same as [].reverse().reduce(...) to make the breakpoints
definitions more natural.
let pipeline = [3600, 60]
.reduceRight(
(ppln, b) => r => [Math.floor(r / b)].concat(ppln(r % b)),
r => [r]
);
Which is the final form. Then you just appy mapping to string with padded 0's on left and join the strings with : separator;
More generalizations
Wrapping the reducer into function
function decompose(total, breakpoints) {
return breakpoints.reduceRight(
(p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
r => [r]
)(total);
}
> decompose(3785, [3600, 60])
< [1, 3, 5]
you now have very general algorithm you can work with. For example:
Convert easily (the weird) us length standards
Given the standards
Unit
Divisions
1 foot
12 inches
1 yard
3 feet
1 mile
1760 yards
> decompose(123_456, [1760 * 3 * 12, 3 * 12, 12])
< [1, 1669, 1, 0]
123456 in = 1 mi, 1669 yd, 1 feet and 0 in
Or you can somewhat convert to decimal or binary representations
> decompose(123_456, [100_000, 10_000, 1000, 100, 10])
< [1, 2, 3, 4, 5, 6]
> decompose(127, [128, 64, 32, 16, 8, 4, 2])
< [0, 1, 1, 1, 1, 1, 1, 1]
Works also with floating point breakpoints
Since Javascript supports mod operator with floating point numbers, you can also do
> decompose(26.5, [20, 2.5])
< [1, 2, 1.5]
The edge case of no breakpoints is also naturally covered
> decompose(123, [])
< [123]
Here is an extension to Number class. toHHMMSS() converts seconds to an hh:mm:ss string.
Number.prototype.toHHMMSS = function() {
var hours = Math.floor(this / 3600) < 10 ? ("00" + Math.floor(this / 3600)).slice(-2) : Math.floor(this / 3600);
var minutes = ("00" + Math.floor((this % 3600) / 60)).slice(-2);
var seconds = ("00" + (this % 3600) % 60).slice(-2);
return hours + ":" + minutes + ":" + seconds;
}
// Usage: [number variable].toHHMMSS();
// Here is a simple test
var totalseconds = 1234;
document.getElementById("timespan").innerHTML = totalseconds.toHHMMSS();
// HTML of the test
<div id="timespan"></div>
Easy to follow version for noobies:
var totalNumberOfSeconds = YOURNUMBEROFSECONDS;
var hours = parseInt( totalNumberOfSeconds / 3600 );
var minutes = parseInt( (totalNumberOfSeconds - (hours * 3600)) / 60 );
var seconds = Math.floor((totalNumberOfSeconds - ((hours * 3600) + (minutes * 60))));
var result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
console.log(result);
This function should do it :
var convertTime = function (input, separator) {
var pad = function(input) {return input < 10 ? "0" + input : input;};
return [
pad(Math.floor(input / 3600)),
pad(Math.floor(input % 3600 / 60)),
pad(Math.floor(input % 60)),
].join(typeof separator !== 'undefined' ? separator : ':' );
}
Without passing a separator, it uses : as the (default) separator :
time = convertTime(13551.9941351); // --> OUTPUT = 03:45:51
If you want to use - as a separator, just pass it as the second parameter:
time = convertTime(1126.5135155, '-'); // --> OUTPUT = 00-18-46
See also this Fiddle.
Chiming in on this old thread -- the OP stated HH:MM:SS, and many of the solutions work, until you realize you need more than 24 hours listed. And maybe you don't want more than a single line of code. Here you go:
d=(s)=>{f=Math.floor;g=(n)=>('00'+n).slice(-2);return f(s/3600)+':'+g(f(s/60)%60)+':'+g(s%60)}
It returns H+:MM:SS. To use it, simply use:
d(91260); // returns "25:21:00"
d(960); // returns "0:16:00"
...I tried to get it to use the least amount of code possible, for a nice one-liner approach.
For the special case of HH:MM:SS.MS (eq: "00:04:33.637") as used by FFMPEG to specify milliseconds.
[-][HH:]MM:SS[.m...]
HH expresses the number of hours, MM the number of minutes for a
maximum of 2 digits, and SS the number of seconds for a maximum of 2
digits. The m at the end expresses decimal value for SS.
/* HH:MM:SS.MS to (FLOAT)seconds ---------------*/
function timerToSec(timer){
let vtimer = timer.split(":")
let vhours = +vtimer[0]
let vminutes = +vtimer[1]
let vseconds = parseFloat(vtimer[2])
return vhours * 3600 + vminutes * 60 + vseconds
}
/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
let o = new Date(0)
let p = new Date(sec*1000)
return new Date(p.getTime()-o.getTime())
.toISOString()
.split("T")[1]
.split("Z")[0]
}
/* Example: 7hours, 4 minutes, 33 seconds and 637 milliseconds */
const t = "07:04:33.637"
console.log(
t + " => " +
timerToSec(t) +
"s"
)
/* Test: 25473 seconds and 637 milliseconds */
const s = 25473.637 // "25473.637"
console.log(
s + "s => " +
secToTimer(s)
)
Example usage, a milliseconds transport timer:
/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
let o = new Date(0)
let p = new Date(sec*1000)
return new Date(p.getTime()-o.getTime())
.toISOString()
.split("T")[1]
.split("Z")[0]
}
let job, origin = new Date().getTime()
const timer = () => {
job = requestAnimationFrame(timer)
OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}
requestAnimationFrame(timer)
span {font-size:4rem}
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>
Example usage, binded to a media element
/* Seconds to (STRING)HH:MM:SS.MS --------------*/
function secToTimer(sec){
let o = new Date(0)
let p = new Date(sec*1000)
return new Date(p.getTime()-o.getTime())
.toISOString()
.split("T")[1]
.split("Z")[0]
}
VIDEO.addEventListener("timeupdate", function(e){
OUT.textContent = secToTimer(e.target.currentTime)
}, false)
span {font-size:4rem}
<span id="OUT"></span><br>
<video id="VIDEO" width="400" controls autoplay>
<source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
</video>
Outside the question, those functions written in php:
<?php
/* HH:MM:SS to (FLOAT)seconds ------------------*/
function timerToSec($timer){
$vtimer = explode(":",$timer);
$vhours = (int)$vtimer[0];
$vminutes = (int)$vtimer[1];
$vseconds = (float)$vtimer[2];
return $vhours * 3600 + $vminutes * 60 + $vseconds;
}
/* Seconds to (STRING)HH:MM:SS -----------------*/
function secToTimer($sec){
return explode(" ", date("H:i:s", $sec))[0];
}
After looking at all the answers and not being happy with most of them, this is what I came up with. I know I am very late to the conversation, but here it is anyway.
function secsToTime(secs){
var time = new Date();
// create Date object and set to today's date and time
time.setHours(parseInt(secs/3600) % 24);
time.setMinutes(parseInt(secs/60) % 60);
time.setSeconds(parseInt(secs%60));
time = time.toTimeString().split(" ")[0];
// time.toString() = "HH:mm:ss GMT-0800 (PST)"
// time.toString().split(" ") = ["HH:mm:ss", "GMT-0800", "(PST)"]
// time.toTimeString().split(" ")[0]; = "HH:mm:ss"
return time;
}
I create a new Date object, change the time to my parameters, convert the Date Object to a time string, and removed the additional stuff by splitting the string and returning only the part that need.
I thought I would share this approach, since it removes the need for regex, logic and math acrobatics to get the results in "HH:mm:ss" format, and instead it relies on built in methods.
You may want to take a look at the documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
below is the given code which will convert seconds into hh-mm-ss format:
var measuredTime = new Date(null);
measuredTime.setSeconds(4995); // specify value of SECONDS
var MHSTime = measuredTime.toISOString().substr(11, 8);
Get alternative method from Convert seconds to HH-MM-SS format in JavaScript
var time1 = date1.getTime();
var time2 = date2.getTime();
var totalMilisec = time2 - time1;
alert(DateFormat('hh:mm:ss',new Date(totalMilisec)))
/* ----------------------------------------------------------
* Field | Full Form | Short Form
* -------------|--------------------|-----------------------
* Year | yyyy (4 digits) | yy (2 digits)
* Month | MMM (abbr.) | MM (2 digits)
| NNN (name) |
* Day of Month | dd (2 digits) |
* Day of Week | EE (name) | E (abbr)
* Hour (1-12) | hh (2 digits) |
* Minute | mm (2 digits) |
* Second | ss (2 digits) |
* ----------------------------------------------------------
*/
function DateFormat(formatString,date){
if (typeof date=='undefined'){
var DateToFormat=new Date();
}
else{
var DateToFormat=date;
}
var DAY = DateToFormat.getDate();
var DAYidx = DateToFormat.getDay();
var MONTH = DateToFormat.getMonth()+1;
var MONTHidx = DateToFormat.getMonth();
var YEAR = DateToFormat.getYear();
var FULL_YEAR = DateToFormat.getFullYear();
var HOUR = DateToFormat.getHours();
var MINUTES = DateToFormat.getMinutes();
var SECONDS = DateToFormat.getSeconds();
var arrMonths = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var arrDay=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
var strMONTH;
var strDAY;
var strHOUR;
var strMINUTES;
var strSECONDS;
var Separator;
if(parseInt(MONTH)< 10 && MONTH.toString().length < 2)
strMONTH = "0" + MONTH;
else
strMONTH=MONTH;
if(parseInt(DAY)< 10 && DAY.toString().length < 2)
strDAY = "0" + DAY;
else
strDAY=DAY;
if(parseInt(HOUR)< 10 && HOUR.toString().length < 2)
strHOUR = "0" + HOUR;
else
strHOUR=HOUR;
if(parseInt(MINUTES)< 10 && MINUTES.toString().length < 2)
strMINUTES = "0" + MINUTES;
else
strMINUTES=MINUTES;
if(parseInt(SECONDS)< 10 && SECONDS.toString().length < 2)
strSECONDS = "0" + SECONDS;
else
strSECONDS=SECONDS;
switch (formatString){
case "hh:mm:ss":
return strHOUR + ':' + strMINUTES + ':' + strSECONDS;
break;
//More cases to meet your requirements.
}
}
I just wanted to give a little explanation to the nice answer above:
var totalSec = new Date().getTime() / 1000;
var hours = parseInt( totalSec / 3600 ) % 24;
var minutes = parseInt( totalSec / 60 ) % 60;
var seconds = totalSec % 60;
var result = (hours < 10 ? "0" + hours : hours) + "-" + (minutes < 10 ? "0" + minutes : minutes) + "-" + (seconds < 10 ? "0" + seconds : seconds);
On the second line, since there are 3600 seconds in 1 hour, we divide the total number of seconds by 3600 to get the total number of hours. We use parseInt to strip off any decimal. If totalSec was 12600 (3 and half hours), then parseInt( totalSec / 3600 ) would return 3, since we will have 3 full hours. Why do we need the % 24 in this case? If we exceed 24 hours, let's say we have 25 hours (90000 seconds), then the modulo here will take us back to 1 again, rather than returning 25. It is confining the result within a 24 hour limit, since there are 24 hours in one day.
When you see something like this:
25 % 24
Think of it like this:
25 mod 24 or what is the remainder when we divide 25 by 24
None of the answers here satisfies my requirements as I want to be able to handle
Large numbers of seconds (days), and
Negative numbers
Although those are not required by the OP, it's good practice to cover edge cases, especially when it takes little effort.
It's pretty obvious is that the OP means a NUMBER of seconds when he says seconds. Why would peg your function on String?
function secondsToTimeSpan(seconds) {
const value = Math.abs(seconds);
const days = Math.floor(value / 1440);
const hours = Math.floor((value - (days * 1440)) / 3600);
const min = Math.floor((value - (days * 1440) - (hours * 3600)) / 60);
const sec = value - (days * 1440) - (hours * 3600) - (min * 60);
return `${seconds < 0 ? '-':''}${days > 0 ? days + '.':''}${hours < 10 ? '0' + hours:hours}:${min < 10 ? '0' + min:min}:${sec < 10 ? '0' + sec:sec}`
}
secondsToTimeSpan(0); // => 00:00:00
secondsToTimeSpan(1); // => 00:00:01
secondsToTimeSpan(1440); // => 1.00:00:00
secondsToTimeSpan(-1440); // => -1.00:00:00
secondsToTimeSpan(-1); // => -00:00:01
Simple function to convert seconds into in hh:mm:ss format :
function getHHMMSSFromSeconds(totalSeconds) {
if (!totalSeconds) {
return '00:00:00';
}
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor(totalSeconds % 3600 / 60);
const seconds = totalSeconds % 60;
const hhmmss = padTo2(hours) + ':' + padTo2(minutes) + ':' + padTo2(seconds);
return hhmmss;
}
// function to convert single digit to double digit
function padTo2(value) {
if (!value) {
return '00';
}
return value < 10 ? String(value).padStart(2, '0') : value;
}
Here is a function to convert seconds to hh-mm-ss format based on powtac's answer here
jsfiddle
/**
* Convert seconds to hh-mm-ss format.
* #param {number} totalSeconds - the total seconds to convert to hh- mm-ss
**/
var SecondsTohhmmss = function(totalSeconds) {
var hours = Math.floor(totalSeconds / 3600);
var minutes = Math.floor((totalSeconds - (hours * 3600)) / 60);
var seconds = totalSeconds - (hours * 3600) - (minutes * 60);
// round seconds
seconds = Math.round(seconds * 100) / 100
var result = (hours < 10 ? "0" + hours : hours);
result += "-" + (minutes < 10 ? "0" + minutes : minutes);
result += "-" + (seconds < 10 ? "0" + seconds : seconds);
return result;
}
Example use
var seconds = SecondsTohhmmss(70);
console.log(seconds);
// logs 00-01-10
There are lots of options of solve this problem, and obvious there are good option suggested about, But I wants to add one more optimized code here
function formatSeconds(sec) {
return [(sec / 3600), ((sec % 3600) / 60), ((sec % 3600) % 60)]
.map(v => v < 10 ? "0" + parseInt(v) : parseInt(v))
.filter((i, j) => i !== "00" || j > 0)
.join(":");
}
if you don't wants formatted zero with less then 10 number, you can use
function formatSeconds(sec) {
return parseInt(sec / 3600) + ':' + parseInt((sec % 3600) / 60) + ':' + parseInt((sec % 3600) % 60);
}
Sample Code http://fiddly.org/1c476/1
In one line, using T.J. Crowder's solution :
secToHHMMSS = seconds => `${Math.floor(seconds / 3600)}:${Math.floor((seconds % 3600) / 60)}:${Math.floor((seconds % 3600) % 60)}`
In one line, another solution that also count days :
secToDHHMMSS = seconds => `${parseInt(seconds / 86400)}d ${new Date(seconds * 1000).toISOString().substr(11, 8)}`
Source : https://gist.github.com/martinbean/2bf88c446be8048814cf02b2641ba276
var sec_to_hms = function(sec){
var min, hours;
sec = sec - (min = Math.floor(sec/60))*60;
min = min - (hours = Math.floor(min/60))*60;
return (hours?hours+':':'') + ((min+'').padStart(2, '0')) + ':'+ ((sec+'').padStart(2, '0'));
}
alert(sec_to_hms(2442542));
Have you tried adding seconds to a Date object?
Date.prototype.addSeconds = function(seconds) {
this.setSeconds(this.getSeconds() + seconds);
};
var dt = new Date();
dt.addSeconds(1234);
A sample:
https://jsfiddle.net/j5g2p0dc/5/
Updated:
Sample link was missing so I created a new one.
You can also use below code:
int ss = nDur%60;
nDur = nDur/60;
int mm = nDur%60;
int hh = nDur/60;
For anyone using AngularJS, a simple solution is to filter the value with the date API, which converts milliseconds to a string based on the requested format. Example:
<div>Offer ends in {{ timeRemaining | date: 'HH:mm:ss' }}</div>
Note that this expects milliseconds, so you may want to multiply timeRemaining by 1000 if you are converting from seconds (as the original question was formulated).
I ran into the case some have mentioned where the number of seconds is more than a day. Here's an adapted version of #Harish Anchu's top-rated answer that accounts for longer periods of time:
function secondsToTime(seconds) {
const arr = new Date(seconds * 1000).toISOString().substr(11, 8).split(':');
const days = Math.floor(seconds / 86400);
arr[0] = parseInt(arr[0], 10) + days * 24;
return arr.join(':');
}
Example:
secondsToTime(101596) // outputs '28:13:16' as opposed to '04:13:16'
String.prototype.toHHMMSS = function () {
var sec_num = parseInt(this, 10); // don't forget the second param
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
return hours+':'+minutes+':'+seconds;
}
Usage Example
alert("186".toHHMMSS());

Create an array with time intervals and add 2 hours

I need to create an array of elements in javascript, which add 2 hours to a certain time I set.
I give an example. The time is
14:00.
I need, to create an array that contains all 30 minute intervals up to 16:00.
Ex
14:00
14:30
15:00
15:30
Here is a function that produces the time specifications as strings. It can take an optional second argument to specify the end-time (16:00 in your question).
Two utility functions convert a time string to (and from) a number of minutes.
Finally, the result array is created with Array.from:
const toMinutes = str => str.split(":").reduce((h, m) => h * 60 + +m);
const toString = min => (Math.floor(min / 60) + ":" + (min % 60))
.replace(/\b\d\b/, "0$&");
function slots(startStr, endStr="16:00") {
let start = toMinutes(startStr);
let end = toMinutes(endStr);
return Array.from({length: Math.floor((end - start) / 30) + 1}, (_, i) =>
toString(start + i * 30)
);
}
console.log(slots("14:00"));
What I would do was to create two methods: addTime and createDateArray.
On addTime function we use to convert a timestamp into a Date object so it is easier for you to manage rather than an 14:00 string.
const addTime = (_dateTimestamp, addHours, addMinutes, addSeconds) => {
const date = new Date();
date.setTime( _dateTimestamp );
const newDate = new Date();
if(addHours) newDate.setHours( date.getHours() + addHours );
if(addMinutes) newDate.setMinutes( date.getMinutes() + addMinutes );
if(addSeconds) newDate.setSeconds( date.getSeconds() + addSeconds );
return newDate;
}
const createDateArray = (date, minuteInterval, amount) => {
let array = [];
for(let i = 1; i <= amount; i++) {
const time = addTime( date, 0, minuteInterval * i, 0);
array.push( time );
}
return array;
}
const dateToIncrement = new Date().getTime();
const minutesInterval = 30; // every 30 minutes
const amountTimes = 10; // will run through 10 times, so it'll calculate the minutes 10 times
const result = createDateArray( dateToIncrement, minutesInterval, amountTimes );
console.log(result);
You can also use the addTime function for other properties like hours and seconds if you wish by setting the second and last argument of the method.
I hope the code above makes sense and you can make use of it.
Here is function that generates time slots in specified boundaries, it's similar to trincot's answer, but doesn't use regex and works for the edge cases:
const timeStringToMinutes = (timeStr, separator) => timeStr.split(separator).reduce((h, m) => h * 60 + +m);
const minutesToTimeString = (minutes, separator) => {
const minutesPart = (minutes % 60).toString().padStart(2, "0");
const hoursPart = Math.floor(minutes / 60).toString().padStart(2, "0");
return hoursPart + separator + minutesPart;
}
function generateTimeSlots(startStr, endStr, periodInMinutes, separator = ":") {
let startMinutes = timeStringToMinutes(startStr, separator);
let endMinutes = timeStringToMinutes(endStr, separator);
const oneDayInMinutes = 1440;
if (endMinutes >= oneDayInMinutes)
endMinutes = oneDayInMinutes - 1;
if (startMinutes <= 0)
startMinutes = 0;
return Array.from({ length: Math.floor((endMinutes - startMinutes) / periodInMinutes) + 1 }, (_, i) =>
minutesToTimeString(startMinutes + i * periodInMinutes, separator)
);
}
console.log(generateTimeSlots("14:00", "15:30", 30));
You can create a basic function like this :
function getTimes(start) {
start = parseInt(start) * 2 + (+start.slice(-2) > 0);
end = start+60/12;
return Array.from({length: end - start}, (_, i) =>
(((i + start) >> 1) + ":" + ((i + start)%2*3) + "0").replace(/^\d:/, "0$&"));
};
And use with :
getTimes("14:00");

Convert string to time and add 2 hours in JS

i get this time from an external JSON :
"time":"19:45"
I need to add 2 hours from this string.
Is it possible in JS?
Thanks
Try this
let myTime = '19:45'
function getTime(time, addHour) {
let [h, m] = time.split(':');
let date = new Date();
date.setHours(h, m, 0)
date.toString();
let res = `${date.getHours()+addHour}:${date.getMinutes()}`
return res
}
console.log(getTime( myTime, 2 ))
uses String.split to get hourNum and minuteNum, then construct one Date object and uses setTime to add two hours.
function addHours(text, hours=2) {
const [hourNum, minNum] = text.split(':')
const time = new Date(0, 0, 0, hourNum, minNum)
time.setTime(time.getTime() + (hours * 60 * 60 * 1000))
return `${time.getHours()}:${time.getMinutes()}`
}
console.log(addHours('19:45', 2))
console.log(addHours('23:45', 2))
A Date object isn't necessary to do time mathematics, it just means taking account of minutes and seconds (60) and maybe days (24).
E.g.
// Add time to a timestamp, both in in HH:mm format
// If respectDay is true, hours are % 24
function addTime(start, increment, respectDay = false) {
let pad = n => ('0' + n).slice(-2);
let timeToMins = time => time.split(':').reduce((h, m) => h*60 + m*1);
let minsToTime = (mins, respectDay = false) => `${pad((mins / 60 | 0) % (respectDay? 24 : Number.POSITIVE_INFINITY))}:${pad(mins%60)}`;
return minsToTime(timeToMins(start) + timeToMins(increment), respectDay);
}
let time = "19:45";
console.log(addTime(time, '8:23')); // Total time : 28:08
console.log(addTime(time, '8:23', true)); // As day time : 04:08

Moment.js difference/duration from 2 times (not dates)

I don't find any docs about it on moment.js website.
I need to calculate difference from 2 duration time (not dates).
For example:
27:10 - 7:20 = 19:50
where 27 is hours (can be bigger than 24h of a day) and 10 is minutes.
I see moment.js can operatore only with dates?
You can use moment.duration()
var d1, d2, dDiff, diff;
d1 = moment.duration('7:20', 'HH:mm');
d2 = moment.duration('27:10', 'HH:mm');
dDiff = d2.subtract(d1);
diff = dDiff.get('days') + ':day(s) ' + dDiff.get('hours') + ':' + dDiff.get('minutes');
console.log(diff); // "0:day(s) 19:50"
more details: momentjs durations
function getTimeDifference(start, end) {
var s = start.split(':');
var e = end.split(':');
var d = (parseInt(s[0], 10) * 60 + parseInt(s[1], 10)) - (parseInt(e[0], 10) * 60 + parseInt(e[1], 10));
var res = parseInt((d / 60), 10).toString() + ':' + (d % 60).toString();
alert(res);
}
getTimeDifference('27:10' , '7:20');
May be helpful to you...
You can do it using pure maths
function f1(a, b) {
const [hoursA, minutesA] = a.split(':').map(v => parseInt(v, 10));
const [hoursB, minutesB] = b.split(':').map(v => parseInt(v, 10));
let minutesDiff = 60 * (hoursA - hoursB) + (minutesA - minutesB)
const hoursDiff = (minutesDiff - minutesDiff % 60) / 60;
minutesDiff = minutesDiff % 60;
return hoursDiff + ':' + minutesDiff.toString().padStart(2,'0');
}
console.log(f1('27:10','7:20'))
console.log(f1('248:10','7:05'))
or using the date object
function f2(a, b) {
const [hoursA, minutesA] = a.split(':').map(v => parseInt(v, 10));
const [hoursB, minutesB] = b.split(':').map(v => parseInt(v, 10));
const time = new Date(Date.UTC(1970));
time.setUTCHours(hoursA - hoursB, minutesA - minutesB);
return ((time - time % 86400000) / 3600000 + time.getUTCHours()) + ':' + time.getUTCMinutes().toString().padStart(2,'0');
}
console.log(f2('27:10','7:20'))
console.log(f2('248:10','7:05'))
This doesn't need a library, you just need to do some base60 arithmetic.
You simply convert both to minutes, do a subtraction and convert back to hours and minutes
//27:10 - 7:20 = 19:50
function calculateDifference(time1,time2){
var diffMins = toMinutes(time1)-toMinutes(time2);
return toHoursMinutes(diffMins);
}
function toMinutes(time){
var [hrs,mins] = time.split(':').map(x => parseInt(x,10));
return hrs*60 + mins;
}
function toHoursMinutes(mins)
{
return Math.floor(mins/60) + ":" + (mins%60).toString().padStart('0',2);
}
console.log(calculateDifference("27:10","7:20"));

Categories