How can I understand what this javascript timer means in detail? - javascript

I created a countdown / timer a few weeks ago using Javascript. The code is also executed correctly by the browser.
Today I looked at the code again and I make notes (Javascript comments) to understand the code and what exactly it does and to better understand Javascrpit.
I'm stuck at the moment. Here's a small piece of code that I absolutely don't understand.
What does the modulo operator do with time? Seconds, minutes, hours...
What exactly does y do?
and why are tenary operators used?
I would be very grateful if someone could explain to me in their own words what exactly the code does. thanks
function timer() {
let seconds = count % 60;
let minutes = Math.floor(count / 60);
let hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
y = ((minutes>0) ? ((minutes>9) ? minutes : '0'+minutes) + ":" : "")
y += (seconds>9 || minutes == 0) ? seconds : '0'+seconds;
Same Code with my Comments :)
function timer() {
// SET VARIABLE FOR SECONDS = DONT KKNOW WHAT count % 60 means ???
let seconds = count % 60;
// SET VARIABLE FOR MINUTES = DONT KKNOW WHAT Math.floor(count / 60) means ???
let minutes = Math.floor(count / 60);
// SET VARIABLE FOR MINUTES = DONT KKNOW WHAT Math.floor(minutes / 60) ???
let hours = Math.floor(minutes / 60);
// WHY USING %= OPERATER ???
minutes %= 60;
hours %= 60;
// DONT UNDERSTAND Y ??? WHY USING TENARY OPERATORS ???
y = ((minutes>0) ? ((minutes>9) ? minutes : '0'+minutes) + ":" : "")
y += (seconds>9 || minutes == 0) ? seconds : '0'+seconds;
EDIT: count = 3600 SECONDS

You don't explain what count is, but it would appear to be a duration in seconds.
The modulo operator and the floor(a/b) operations are being used to convert the duration in seconds into a base-60 (i. e. Sumerian) representation, i. e., in hours, minutes, and seconds.
y is being built up to show the hours, minutes, and seconds as two decimal digits each, separated with colons, as is conventional to represent a time duration in hours, minutes, and seconds. So, for example, the final value might be "6:01:02" for six hours, one minute, and two seconds. For each base-sixty "digit", we want two decimal digits. The normal conversion of numbers to decimal notation does not include any leading zeros. If the answer were to have only one decimal digit, we have to append one leading zero to the beginning. So, for example, for 8, we would like to see "08".

Related

How can I calulate the time since 9:30 AM in JavaScript?

Okay, so I am trying to calculate the time since 9:30 in the morning in Google Apps Script, and I want the output to look like this: XX hrs XX mins. the problem is when I try calculating the minutes since 9:30, of course, it gives me all the minutes, not just the leftover minutes after I've calculated the hours. I need the minutes to be a decimal so I can times it by 60 and display the output in a cell. This is the code I'm currently using:
function CALCTIME() {
const minutes = 1000 * 60;
const hours = minutes * 60;
const days = hours * 24;
const years = days * 365;
var now = new Date(),
then = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate(),
9,30,0),
diff = now.getTime() - then.getTime();
let hrs = diff / hours;
let mins = Math.floor((diff / minutes) % 60);
return Math.floor(hrs) + " hrs " + mins + " mins";
}
The issue is not the hrs, I have that all good. The minutes are the problem because I can't figure out how to replace just an index from a string. I've looked and tried the methods shown on these web pages and Stack Exchange links for answers and I couldn't find any:
https://www.w3schools.com/jsref/jsref_replace.asp
How do I replace a character at a particular index in JavaScript?
Questions: What do you expect these statements to do and why? mins.replaceAt(0, "0."); mins % 60; The first statement I expected to replace the first character in mins with "0." but then, #jabaa pointed out that I couldn't replace a number for a string, which I totally forgot and didn't take into account. The second statement I just forgot to put mins = mins % 60; which probably wouldn't have solved my problem anyway, I just forgot to put that there.
I've answered your questions, but someone has already answered my questions.
The reason it is not working is because you have:
diff = now.getTime() - then.getTime();
That line is going to get the time difference from now and 9:30am.
var hrs = diff / hours;
var mins = diff / minutes;
The two lines above are getting their own things. The first is how many hours and the second is how many minutes. So inherently you will be getting all the minutes and not the leftovers. There are multiple ways to fix it. Below is one way where the hours are right, so we take out every full hour from the minute's section.
Could look something like this:
let hrs = diff / hours;
let mins = (diff / minutes) % 60;
ALSO: The following line of code you have does nothing because you're not giving it anywhere to be stored in.
mins % 60
To fix you can do something like:
let testvar = mins % 60;

How to add numbers in a 'clock-like' way?

I am currently working with hours as numbers, such as 2230 being equivalent to 22:30. I would like to be able to add numbers to it and sum as if they were minutes added to hours
2030 + 60 = 2130 //and not 2090
2330 + 120 = 0230 //and not 2350
Is there a library or function to doing this? Or perhaps I should change the way I am handling hours?
I don't recommend doing this, but if you want to do it, you have to handle the fact that you're pretending an hour is 100 minutes. You do that by extracting the real hours and minutes from the fake value, doing the math on them, and then reassembling them, something along these lines:
function toHoursAndMinutes(value) {
// Get hours: `value` divided by 100
const hours = Math.floor(value / 100);
// Get minutes: the remainder of dividing by 100
const minutes = value % 100;
// Return them
return [hours, minutes];
}
function fromHoursAndMinutes(hours, minutes) {
// Reassemble the number where hours are worth 100
return hours * 100 + minutes;
}
function add(a, b) {
// Get `a`'s hours and minutes
const [ahours, aminutes] = toHoursAndMinutes(a);
// Get `b`'s
const [bhours, bminutes] = toHoursAndMinutes(b);
// Add the hours together, plus any from adding the minutes
const hours = ahours + bhours + Math.floor((aminutes + bminutes) / 60);
// Add the minutes together, ignoring extra hours
const minutes = (aminutes + bminutes) % 60;
// Reassemble
return fromHoursAndMinutes(hours, minutes);
}
Live Example:
function toHoursAndMinutes(value) {
// Get hours: `value` divided by 100
const hours = Math.floor(value / 100);
// Get minutes: the remainder of dividing by 100
const minutes = value % 100;
// Return them
return [hours, minutes];
}
function fromHoursAndMinutes(hours, minutes) {
// Reassemble the number where hours are worth 100
return hours * 100 + minutes;
}
function add(a, b) {
// Get `a`'s hours and minutes
const [ahours, aminutes] = toHoursAndMinutes(a);
// Get `b`'s
const [bhours, bminutes] = toHoursAndMinutes(b);
// Add the hours together, plus any from adding the minutes
// The % 24 wraps around
const hours = (ahours + bhours + Math.floor((aminutes + bminutes) / 60)) % 24;
// Add the minutes together, ignoring extra hours
const minutes = (aminutes + bminutes) % 60;
// Reassemble
return fromHoursAndMinutes(hours, minutes);
}
console.log(add(2030, 60));
console.log(add(2330, 120));
But again, I don't recommend this. Instead, work with time values (Date or just milliseconds-since-the-Epoch, etc.) and convert for display when you need to display it.
Note that 50 rather than 0250, for two reasons: 1. 2330 + 120 is 2450 which is 00:50, not 02:50, and numbers don't have leading spaces except in string representations.
Here's my implementation of it
function add(current, time) {
const hours = Math.floor(time / 60);
const minutes = time % 60;
const currentMinutes = parseInt(current.toString().slice(2));
const currentHours = parseInt(current.toString().slice(0, 2));
const newMinutes = (currentMinutes + minutes) % 60;
const additionalHours = (currentMinutes + minutes) > 60 ? 1 : 0;
const newHours = (currentHours + hours + additionalHours) % 24;
return `${newHours < 10 ? '0' : ''}${newHours}${newMinutes < 10 ? '0' : ''}${newMinutes}`;
}
console.log(add(2030, 60)); // 2130
console.log(add(2330, 120)); // 0130
here is the working code for your clock.
var nowTime = '2350'; //current time in String..
var newMin = 120; // min you want to add in int..
var tMinutes = parseInt(nowTime.toString().slice(2)); //taking out the min
var tHours = parseInt(nowTime.toString().slice(0, 2)); //taking out the hr
var newMinutes = (newMin + tMinutes) % 60;
var newHr = tHours + parseInt(((newMin + tMinutes) / 60));
var newTime = `${newHr >= 24 ? newHr-24 : newHr}${newMinutes}`;
newTime = newTime.length < 4 ? '0'+newTime : newTime;
console.log(newTime);
If you want to handle date math, a library is probably best, because date math is hard, and the source of so many bugs if done wrong. Now, knowing how to do date math is a great thing to learn though, and reading through the source code of date math libraries is a good way to do that. Luxon is a good library with duration objects that can do what you need easily, and has readable source code. Other duration libraries also exist, so take a look at a few of those and see what you like the best. You can also abuse he built-in Date library to act like a duration object, but I don't think that's worth it.
But libraries aside, let's analyze the problem and what you might want to consider in solving it.
First off, I would say your first problem is trying to use a data type that isn't designed for what you want. A single integer is not a good idea for representing two values with different units. That is sort of what T.J. meant when he said it's a presentation concept. You have one object, but it's not really an integer in behavior. And date is close, but not quite right. So let's make a class. Duration seems like a good name:
class Duration { … }
We know it has two parts, hours and minutes. Also, it seems a good idea to just use one unit and convert them. (You wouldn't have to, but it actually makes the math easier if you do the conversion):
class Duration {
constructor ({hours = 0, minutes = 0}) {
this.totalMinutes = hours * 60 + minutes
}
}
Now lets make some getters to get just the minutes section and the hours section:
class Duration {
…
// just minutes that don't fit in hours
get minutes () { return this.totalMinutes % 60 }
get hours () { return Math.floor(this.totalMinutes / 60) }
// and also let's present it as the string you wanted:
asDisplayString() { return `${this.hours*100 + this.minutes}` }
}
Now we need to add them together. Some languages would let you use + for this, but javascript has limits on what we can make + do, so we'll add our own method. Note that because of how our constructor works, we can have more than 60 minutes when we initialize the values. Is this a good idea? Maybe. Depends on how you want the object to behave. (While we'll go with it for this example, there are definite arguments against it, mostly because it is a bit confusing that get minutes doesn't return over 60 - but it's also makes a certain sense at the same time).
class Duration {
…
add (otherDuration) {
return new Duration({minutes: this.totalMinutes + otherDuration.totalMinutes})
}
}
And now we can add our duration objects together, and the math is taken care of for us.
class Duration {
constructor ({hours = 0, minutes = 0}) {
this.totalMinutes = hours * 60 + minutes
}
// just minutes that don't fit in hours
get minutes () { return this.totalMinutes % 60 }
get hours () { return Math.floor(this.totalMinutes / 60) }
// and also let's present it as the string you wanted:
asDisplayString() { return `${this.hours*100 + this.minutes}` }
add (otherDuration) {
return new Duration({minutes: this.totalMinutes + otherDuration.totalMinutes})
}
}
d1 = new Duration({hours:20, minutes: 30})
d2 = new Duration({minutes: 50})
console.log(d1.asDisplayString(), '+', d2.asDisplayString(), '=', d1.add(d2).asDisplayString())

How to turn a decimaled number into a framerate designation in javascript

I am using the flowplayer video player and a flowplayer function is giving me a decimal for the point on the player timeline. i.e. Instead of giving me a traditional:
00:00:01:03
timestamp, it just gives me
1.03333
or the equivalent. The
.033333
essentially serves as the frames although I believe it is, in that case based on a 10 fps framerate (which is fine for what I am doing.)
I am not skilled at all in working with numbers/decimals in JS. How can I convert that
1.033333
into a timestamp like
00:00:01:03?
Use division and modulus: x % 60 will give you the remainder of dividing by 60 (363 % 60 is 3), then floor divide (Math.floor(363 / 60) is 6) and use modulus again, repeat.
So:
var timestamp = 1.03333;
var seconds = timestamp % 60;
timestamp = Math.floor(timestamp / 60);
var minutes = timestamp % 60;
timestamp = Math.floor(timestamp / 60);
var hours = timestamp;

JavaScript Freezes Browser

I'm trying to make a countdown timer for each row of a table based on a hidden field containing the ammount of seconds to finish. Here is what I have done so far:
function countdownProcedure() {
var interval = 1000;
var i = 0;
var seconds;
$(".rfqTbl tr").each(function() {
if(i > 0) {
seconds = $(this).find("#sqbTimestamp").text();
var days = Math.floor(seconds / (60*60*24));
seconds -= days * 60 * 60 * 24;
var hours = Math.floor(seconds / (60*60));
seconds -= hours * 60 * 60;
var minutes = Math.floor(seconds / 60);
seconds -= minutes * 60;
if(days < 1) { days=""; }
$(this).find("#countDown").html(days + "<pre> Days</pre> " + hours + "<pre>:</pre>" + minutes + "<pre>:</pre>" + seconds);
if(days > 1) {
$(this).find("#countDown").css({
'color':'#2A7F15',
'font-weight':'bold'
});
};
if(days < 1) {
$(this).find('#countDown').css('color','red');
$(this).find('#countDown pre:nth-of-type(1)').css('display','none');
}
if(seconds < 10) {
$(this).find("#countDown").append(" ");
};
if(minutes < 60){ interval = 1000; };
}
i++;
});
setInterval(countdownProcedure,interval);
};
However, my problem is that I'm trying to get this function to run (realistically every second or 30) so that the time shown would update and hence 'countdown'. The problem I am having is in firefox and safari the browsers are just hanging after the first countdown and chrome is doing nothing (I guess it has a safe guard to prevent it from hanging).
Any help would be much appreciated!
You are running a multitude of setInterval() calls, so the event queue gets crowded with your function.
I think, what you mean is more like setTimeout() at the end of your function.
function countdownProcedure(){
// all your logic
setTimeout(countdownProcedure,interval);
};
The difference is, that setInterval() will run your code every x seconds, until you tell it to stop.
setTimeout() on the other hand, just runs your code once after x seconds.
Change all ids for clases Ex: #sqbTimestamp for .sqbTimestamp
in an HTML document, should exists only 1 element with some id, if you set multiple elements with same id, unexpected results (as browser hanging) can occurrs.
Also, you are setting days="" and then do the following compare if (days > 1)
I think your algorithm is wrong. You are recursively setting intervals which are calling themselves every time and setting new intervals and so on...
You must change your algorithm a bit to get it clean.

Setting a countdown timer and having problems with IE

I've set up a countdown timer with 1 sec interval and increment / decrement in mill secs..
I then searched for something that would give me the value in minutes/seconds. I came up with the following:
var timer = 130000;
var mins = Math.floor((timer % 36e5) / 6e4),
secs = Math.floor((timer % 6e4) / 1000);
The above code works on Safari, Chrome and Firefox with no problem. When I get to Internet Explorer, it doesn't work at all.
Is there another way of doing it that would work on all browsers?
Try with removing the exponetial.
var timer = 130000;
var mins = Math.floor((timer % 3600000) / 60000),
secs = Math.floor((timer % 60000) / 1000);
Read more about Exponential Notation.
An Exponential Notation if number with format a x 10^n, where 1<= a < 10 and n is integer with positive or negative value.
For example:
36e5
= 36 x 10^5
= 36 x 100000
= 3600000
ans so on.

Categories

Resources