I am trying to convert time duration from the format of mm:ss.mss to entirely milliseconds and back.
I've already have a working function for converting from milliseconds to duration but I cannot seem to get it the other way around.
Lets say for instance that I have the duration 32:29.060, I want to convert it to milliseconds. For that I use this function:
function millisecondsToTime(ms, digits) {
digits = digits || 12;
return new Date(ms).toISOString().slice(23-digits, -1);
}
var a = millisecondsToTime(5549060, 9);
but whenever I try to convert back to time duration, I fail. I've tried parsing individually the minutes, seconds and milliseconds but it doesn't seem to work.
Here is the code that I've used for it:
var firstSplit = a.split(':')
var minutes = firstSplit[0]; //1
var secondSplit = firstSplit[1].split('.');
var seconds = secondSplit[0]; //2
var millisec = secondSplit[1]; //3
var conversion = ((+minutes) * 60 + (+seconds) * 60 + (+millisec))*1000;
I have an input bar which takes the format of mm:ss.mss and I need to convert it to milliseconds. How can I do that?
you can just return a
new Date(ms)
to get a date from ms.
And to get the same date as ms,
date.getTime() // returns ms from date object
Full example:
const ms = 5549060
const date = new Date(ms) // get a date from ms
console.log(date.getTime) // logs 5569060
If your input is a string in the format of mm:ss.mss, and you want to get a date from it, you can use moment.
const moment = require('moment')
const date = moment('22:15.143', 'mm:ss.SSS') // get date from pre specified format
You can use the string methods indexOf() and substr() to get the individual numbers out of your string and calculate the time accordingly.
I'm afraid though your millisecondsToTime() function isn't working properly.
5549060 milliseconds are roughly 92 minutes and it's returning 32:29.060
function backToTime(time) {
var index = time.indexOf(":");
var minutes = time.substr(0, index);
var seconds = time.substr(index + 1, time.indexOf(".") - (index + 1));
var milliseconds = time.substr(time.indexOf(".") + 1, time.length);
return parseInt(minutes * 60 * 1000) + parseInt(seconds * 1000) + parseInt(milliseconds);
}
console.log(backToTime("32:29.060"));
Your conversion to milliseconds is not working, this is basic math approach to both conversions:
let input = 5549060
//toDuration
let seconds = Math.floor(input / 1000);
let ms = input - seconds*1000;
let m = Math.floor(seconds / 60);
let s = seconds - m*60;
duration = m + ":" + s + "." + ms
console.log(duration)
//toMilliseconds
let holder = duration.split(":");
m = parseInt(holder[0]);
holder = holder[1].split(".");
s = parseInt(holder[0]);
ms = parseInt(holder[1]);
milliseconds = (m*60 + s)*1000 + ms
console.log(milliseconds)
If needed add check for ms length to add 0s, if you need it to have length of 3
I think your milliseconds to duration converter will be broken for durations above 60 minutes. This is because using Date the minutes field will wrap over into the minutes after 59 seconds have passed. If you want to get good support for values beyond 59 in your first field, I think maybe moving to a regex-based parser and using multiplication and addition, division and modulo to extract and reduce the fields manually might be nice. Something like this maybe:
var duration = ms => `${(ms / 60000) | 0}`.padStart(2, '0') + `:` + `${ms % 60000 / 1000 | 0}`.padStart(2, '0') + `.` + `${ms % 1000}`.padStart(3, '0')
var millisec = durat => (match => match && Number(match[1]) * 60000 + Number(match[2]) * 1000 + Number(match[3]))(/^([0-9]+)\:([0-5][0-9])\.([0-9]{3})$/.exec(durat))
You can see given the input 5549060, this function provides output 92:29.60, which is exactly 60 seconds greater than your own, and I believe to be correct. Maybe it's intentional for your usecase, but I can't imagine that being so desirable generally...
Related
I apologise in advance for being a complete dunce but these are in fact my very first shaky steps into trying to get something done with Javascript and I feel somewhat lost and confused.
I have the following float: 53.93
This decimal value represents minutes and seconds and it comes from multiplying the longitude I get from the web-browser´s Geolocation API times four (x4). I have this value stored in a variable which I want to convert into minutes and seconds so that I can then add it to the current UTC time so that I can get a new HH:MM:SS time on screen with the added difference(current UTC Time + 53 minutes and 93 seconds.)
I understand that I should first convert times into milliseconds in order to be able to calculate the time difference but I'm stuck at converting the float into minutes and seconds (or should I convert it directly into milliseconds?)
Thank you kindly.
JavaScript's Date works in milliseconds, so if you have a number representing minutes (whether or not including fractional minutes), you can convert that to milliseconds by multiplying it by 60 (to get seconds) and 1000 (to get milliseconds), e.g., multiply by 60,000. But, you've said you have the value 13.48 and later in the text of your question you've said "...current UTC Time + 13 minutes and 48 seconds..." Those are two different things. .48 of a minute is roughly 28.79 seconds, not 48 seconds. So if you really mean that the figure 13.48 is supposed to mean 13 minutes and 48 seconds, the calculation is more compliated:
const value = 13.48;
const wholeMinutes = Math.trunc(value);
const milliseconds = (wholeMinutes * 60 + (value - wholeMinutes)) * 1000;
You can get the current date/time via Date.now(), which gives you milliseconds since The Epoch UTC (Jan 1st 1970 at midnight).
You can create a Date instance from a given milliseconds-since-The-Epoch value via new Date(value).
So if 13.48 represents fractional minutes (13 minutes and roughly 28.79 seconds):
const minutes = 13.48;
const nowPlusThoseMinutes = new Date(Date.now() + (minutes * 60000));
Live Example:
const minutes = 13.48;
const now = Date.now();
const nowPlusThoseMinutes = new Date(now + (minutes * 60000));
console.log(nowPlusThoseMinutes);
console.log(`now = ${new Date(now)}`);
console.log(`nowPlusThoseMinutes = ${nowPlusThoseMinutes}`);
(The () around minutes * 60000 aren't necessary, the * will happen before the + either way because of operator precedence, but they can help make your intent clear to human readers.)
But you mean it to mean 13 minutes and 48 seconds:
const value = 13.48;
const wholeMinutes = Math.trunc(value);
const milliseconds = (wholeMinutes * 60 + (value - wholeMinutes)) * 1000;
const nowPlusValue = new Date(Date.now() + milliseconds);
Live Example:
const value = 13.48;
const wholeMinutes = Math.trunc(value);
const milliseconds = (wholeMinutes * 60 + (value - wholeMinutes)) * 1000;
const now = Date.now();
const nowPlusValue = new Date(now + milliseconds);
console.log(`now = ${new Date(now)}`);
console.log(`nowPlusValue = ${nowPlusValue}`);
I have a string like below
%snd: <00:00:00><00:02:20>
%snd: <00:02:45><00:05:18>
%snd: <00:05:49><00:09:84>
I want to count the time duration between these two tags in each line and show the sum of all the time difference in minutes.Should I have to convert them into proper javascript time object or is there any other direct way I can do it ?
Any help or hint will be highly appreciated.Thank You
If your format is in <minutes:seconds:milliseconds> then pass the string inside <> tags to that function, it will give you time in minutes.Then you can apply your further logic.
function timeToMinutes(time) {
time = time.split(/:/);
return time[0] + (time[1]/60) + time[2]/(60*100);
}
I think it's simpler to avoid Dates altogether. Convert the times to a common denominator, say seconds, do whatever mathematic operations you want on the seconds, then convert back to time at the end.
/* Convert a string in h:mm:ss format to seconds
** #param {string} s - string in hh:mm:ss format
** #returns {number} - time converted to seconds
*/
function parseTime(s) {
var b = s.split(/\D/);
return b[0]*3600 + b[1]*60 + +b[2];
}
/* Convert a time in seconds to hh:mm:ss format
** #param {number} secs - seconds to convert
** #returns {string} - time in hh:mm:ss format
*/
function secondsToTime(secs) {
function z(n){return (n<10?'0':'')+n}
var sign = secs < 0? '-' : '';
secs = Math.abs(secs);
return sign + z(secs / 3600 | 0) + ':' +
z(secs % 3600 / 60 | 0) + ':' +
z(secs % 60);
}
// Get time difference between 00:02:45 and 00:05:18
var diffInSeconds = parseTime('00:05:18') - parseTime('00:02:45');
console.log(secondsToTime(diffInSeconds))
// Deal with -ve difference between 00:05:18 and 00:02:45
var diffInSeconds = parseTime('00:02:45') - parseTime('00:05:18');
console.log(secondsToTime(diffInSeconds))
// Process a time pair (noting that 84 is likely an invalid value but is allowed)
var diff = '<00:05:49><00:09:84>'.match(/\d\d:\d\d:\d\d/g).reduce((a,b)=>secondsToTime(parseTime(b) - parseTime(a)));
console.log(diff);
I am trying to make a small question/answer quiz game using react, and I want to show a timer that counts down every second. Each game will last 10, 15, or 30 minutes at most, so I want to show a timer that updates every second in the bottom of the screen (in big font, of course!), something like 15:00, 14:59, 14:58, and so on until it hits 00:00.
So, given a start time such as 2016-04-25T08:00:00Z, and an end time after adding 15 min of 2016-04-25T08:15:00Z, I want to start the countdown.
My issue is that I am not understanding how to use setIntervals to keep calling my method to find the remaining time.
timeLeft = Math.round(timeLeft/1000) * 1000;
const timer = new Date(timeLeft);
return timer.getUTCMinutes() + ':' + timer.getUTCSeconds();
EDIT: You've edited your question. You will need the time padding, and the method below will be faster than what you are using, but to answer your question about setInterval:
First, define your function to run your timer and decrement each time it's called:
var timeLeft; // this is the time left
var elem; // DOM element where your timer text goes
var interval = null; // the interval pointer will be stored in this variable
function tick() {
timeLeft = Math.round(timeLeft / 1000) * 1000;
const timer = new Date(timeLeft);
var time = timer.getUTCMinutes() + ':' + timer.getUTCSeconds();
elem.innerHTML = time;
timeLeft -= 1000; // decrement one second
if (timeLeft < 0) {
clearInterval(interval);
}
}
interval = setInterval(tick, 1000);
OG Answer:
No, I do not believe there is a built-in way to display time differences.
Let's say you have two date objects:
var start = Date.now();
var end = Date.now() + 15 * 60 * 1000; // 15 minutes
Then you can subtract the two Date objects to get a number of milliseconds between them:
var diff = (end - start) / 1000; // difference in seconds
To get the number of minutes, you take diff and divide it by 60 and floor that result:
var minutes = Math.floor(diff / 60);
To get the number of seconds, you take the modulus to get the remainder after the minutes are removed:
var seconds = diff % 60;
But you want these two padded by zeros, so to do that, you convert to Strings and check if they are two characters long. If not, you prepend a zero:
// assumes num is a whole number
function pad2Digits(num) {
var str = num.toString();
if (str.length === 1) {
str = '0' + str;
}
return str;
}
var time = pad2Digits(minutes) + ':' + pad2Digits(seconds);
Now you have the time in minutes and seconds.
I've been going through the docs and I'm not sure what I'm doing wrong. I need to convert 7200 to 2:00:00. Seems easy? Some attempts:
var duration = 7200;
var display = moment().seconds(duration).format("h:mm:ss");
and...
var duration = 7200;
var display = moment.duration(duration, "seconds"); //can't chain on a format method?
The format comes back correct but the numbers are all wrong. If I use a duration of Math.round(7025.526) or 7025.526 I get 9:19:06 back.
How can I convert seconds to h:mm:ss successfully?
When you use moment().seconds(duration) it will take the current date and time, and then set the seconds component to the value (spilling over into minutes and hours). If you try it at different times you will see that the result changes.
A duration object can't be formatted as a date, because it's simply not a date. It's a length of time without any defined starting or ending point.
To convert the seconds first create an empty moment object, which will be the current date and the time 0:00:00. Then you can set the seconds, which will spill over into minutes and hours.
You would want to use H rather than h to format the hours. That avoids getting times less than an hour as 12:nn:nn instead of 0:nn:nn:
var duration = 7200;
var display = moment({}).seconds(duration).format("H:mm:ss");
let duration = seconds;
let hours = duration/3600;
duration = duration % (3600);
let min = parseInt(duration/60);
duration = duration % (60);
let sec = parseInt(duration);
if (sec < 10) {
sec = `0${sec}`;
}
if (min < 10) {
min = `0${min}`;
}
if (parseInt(hours, 10) > 0) {
return (`${parseInt(hours, 10)} : ${min} : ${sec}`)
}
return (`${min} : ${sec}`)
You can do it manually by calculating hours minutes and seconds
Using the moment-duration-format plugin:
var s = moment.duration(ms).format("h:mm:ss");
Or, just using moment:
var d = moment.duration(ms);
var s = Math.floor(d.asHours()) + moment.utc(ms).format(":mm:ss");
I'm working on a web timesheet where users use timepicker to determine start & end times and I'd like to have the form automatically find the difference between the two times and place it in a 3rd input box. I understand that I need to get the values, convert them to milliseconds, then subtract the first number from the second, convert the difference back to human time and display that in the third box. But I can't seem to wrap my head around time conversion in javascript. Here's what I have so far:
function date1math(){
var date1in = document.getElementById("date-1-in").value;
var date1out = document.getElementById("date-1-out").value;
date1in = date1in.split(":");
date1out = date1out.split(":");
var date1inDate = new Date(0, 0, 0, date1in[0], date1in[1], 0);
var date1outDate = new Date(0, 0, 0, date1out[0], date1out[1], 0);
var date1math = date1outDate.getTime() - date1inDate.getTime();
var hours = Math.floor(date1math / 1000 / 60 / 60);
date1math -= hours * 1000 * 60 * 60;
var minutes = Math.floor(date1math / 1000 / 60);
return (hours < 9 ? "0" : "") + hours + ":" + (minutes < 9 ? "0" : "") + minutes;
document.getElementById("date-1-subtotal").value = date1math(date1in, date1out);
}
I want to take the timepicker result (say 9:00am) from the input date-1-in, the timepicker result (say 5:00pm) from the input date-1-out, and then place the difference as a number in date-1-subtotal.
Presumably the input is a string in the format hh:mm (e.g. 09:54) and that the two strings represent a time on the same day. You don't mention whether an am/pm suffix is included, but it's there in the text so I'll assume it might be.
If daylight saving changes can be ignored, the simplest method is to convert the string to minutes, find the difference, then convert back to hours and minutes, e.g.:
// Convert hh:mm[am/pm] to minutes
function timeStringToMins(s) {
s = s.split(':');
s[0] = /m$/i.test(s[1]) && s[0] == 12? 0 : s[0];
return s[0]*60 + parseInt(s[1]) + (/pm$/i.test(s[1])? 720 : 0);
}
// Return difference between two times in hh:mm[am/pm] format as hh:mm
function getTimeDifference(t0, t1) {
// Small helper function to padd single digits
function z(n){return (n<10?'0':'') + n;}
// Get difference in minutes
var diff = timeStringToMins(t1) - timeStringToMins(t0);
// Format difference as hh:mm and return
return z(diff/60 | 0) + ':' + z(diff % 60);
}
var t0 = '09:15am';
var t1 = '05:00pm';
console.log(getTimeDifference('09:15am', '05:00pm')); // 07:45
console.log(getTimeDifference('09:15', '17:00')); // 07:45
If daylight saving is to be incorporated, you'll need to include the date so that date objects can be created and used for the time difference. The above can use either 12 or 24 hr time format.