How to synchronise a timer for everyone client - javascript

I have a working timer, but it runs from 25 seg every time who the website is visited by a client, I want to synchronise it. F.E. if i visit my webpage in mY Pc, and when it show 15seg left, i visit it from other pc and i want it to show 15 left too.
function timerr(){
var initial = 25000;
var count = initial;
var counter;
var initialMillis;
function timer() {
if (count <= 0) {
clearInterval(counter);
return;
}
var current = Date.now();
count = count - (current - initialMillis);
initialMillis = current;
displayCount(count);
function displayCount(count) {
var res = count / 1000;
if (res<0.1){
document.getElementById("timer").innerHTML = "";
}
else{
tiempo = res.toPrecision(count.toString().length);
tiempo_corto = tiempo.slice(0,-1);
document.getElementById("timer").innerHTML = tiempo_corto;
}
}
clearInterval(counter);
initialMillis = Date.now();
counter = setInterval(timer, 10);
}

If you want everyone to have the same timer count down every 25 seconds and stop at the exact same time, then you can simply use timestamps to keep everything in sync. Here's an example countdown timer that'll restart every 6 seconds (from 5 to 0) and will hit zero at the exact same time for everyone (unless their computer clock is off).
const timerElement = document.getElementById('timer')
const TIMER_DURATION = 6
function step() {
const timestamp = Date.now() / 1000
const timeLeft = (TIMER_DURATION - 1) - Math.round(timestamp) % TIMER_DURATION
timerElement.innerText = timeLeft
const timeCorrection = Math.round(timestamp) - timestamp
setTimeout(step, timeCorrection*1000 + 1000)
}
step()
<p id="timer"></p> seconds
Try it - open this page up in two different tabs and run it. This is set up to automatically account for the fact that setTimeout doesn't always trigger at the delay you asked it to do so (it'll adjust the next setTimeout with a timeCorrection value to correct these issues).
The basic principle is that we're getting the current timestamp and modding it by the amount of time we want this timer to last (6 seconds in the above example). This value will always be the same for everyone, and will always be a number that ranges from 0 to 5. It will also be a number that counts up every second (which is why we then subtract (TIMER_DURATION - 1) from it, to cause the number to count down instead).

Related

javascript countdown timer

I want to create a countdown timer with javascript that will count down every six minutes. When it gets to 00 I will start from 6 minutes. It will continue like this forever. If the browser is refreshed, this countdown will continue. Even if the browser is refreshed, the countdown will not start again from 6 minutes until 00. How can I do this? Someone help with the code.
Welwome to SO. Please, before asking for help try to provide some code before.
For this time, we will help.
let countdown = 6 * 60;
setInterval(function() {
countdown--;
if (countdown === 0) {
countdown = 6 * 60;
}
document.getElementById("countdown").innerHTML = countdown;
}, 1000);
Note that if the browser is refreshed, everything will reinitialize.
To keep track, you'll need a database or store in client browser.
Make a button with the onclick function starting the timer using the setInterval function that has a callback that decreases a second each second from the 6 minutes.In the callback, store the time into localstorage, and make the startingTime value restore from the localstorage time value if the localstorage time value is not 0.
const start = document.querySelector("#start")
const timeP = document.querySelector("#time")
let interval;
const startingTime = 360
let time = startingTime || window.localStorage['time']
console.log(window.localStorage['time'])
const setLocalStorage = () => {
console.log(time);
window.localStorage['time'] = time}
if (time <= 0) {
time = startingTime
setLocalStorage()
}
function calc(s) {
minutes = (s - s % 60) / 60;
seconds = s % 60;
return minutes + ":" + seconds
}
function callback() {
console.log(time);
time--;
timeP.innerHTML = calc(time);
if (time <= 0) {
time = startingTime;
clearInterval(interval);
start.classList.remove("invis")
timeP.classList.add("invis")
}
setLocalStorage();
}
function startTimer() {
interval = setInterval(callback, 1000);
start.classList.toggle("invis");
timeP.classList.remove("invis")
}
start.onclick = startTimer
.invis {
display: none
}
#start {
color: black;
background-color: red;
}
#time {
color: black;
}
<button id="start">START</button>
<p1 id="time" class="invis"></p1>
If you want the timer "not to pause" to run even after you exit the browser then:
you could store the value of Date.now() in localstorage or wherever you want
and get the value on load and subtract that value from the current Date.now() and you have the difference between the times now you can use that difference to do what you want.

Create a timer which resets itself after 24 hours but doesn't get restarted after the page is reset

i'm creating a web app and i'm trying to create a countdown timer for a certain product that is on discount and i'm wondering if there is a way to not reset the timer after the page has been refreshed and when it reaches 0 , wait 24 hours and then reset itself automatically. Here is a picture of a timer down below:
Here is the code of a timer:
var count = 420;
var counter = setInterval(timer, 1000);
function timer() {
count = count - 1;
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
minutes %= 60;
document.getElementById("timer").innerHTML = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}) + ":" + (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); // watch for spelling
document.getElementById("timer2").innerHTML = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}) + ":" + (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}); // watch for spelling
}
It's not a great option, but when the user first lands on the page, create a timer with a new count down and store the counter value in the local storage, and update it every second in the storage as well.
And the next time the user comes, you can check if you already have the counter in the storage, use that value of the counter to create the timer.
Here's some documentation on using localStorage - https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
You can use localStorage to persist a value across page loads. When talking about a timer, it makes sense to save the time at which the timer was started. That way when a visitor comes back your code can tell exactly how much time is left on it.
// Get the time stamp (in milliseconds) that the timer started
var timerStart = window.localStorage.getItem('timerStart')
if (!timerStart){
// If a timer was never started, start one
timerStart = new Date().getTime()
window.localStorage.setItem('timerStart', timerStart)
}
// Update the timer every 1/10th of a second
setInterval(timer, 100);
function timer() {
// Use the start time to computer the number of
// seconds left on the timer
var count = 7 * 60 - Math.round((new Date().getTime() - timerStart) / 1000)
if (count < 0) {
clearInterval(timer);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
minutes %= 60;
document.getElementById("timer").innerHTML = (minutes).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false}) + ":" + (seconds).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false});
}

setInterval halted when I move between browser tabs in react [duplicate]

function initTimer(timeLeft) {
var Me = this,
TotalSeconds = 35,
Seconds = Math.floor(timeLeft);
var x = window.setInterval(function() {
var timer = Seconds;
if(timer === -1) { clearInterval(x); return; }
$('#div').html('00:' + (timer < 10 ? '0' + timer : timer));
Seconds--;
},1000);
}
I have this code. Everything works fine, when this tab is active in browser, but when I change tab and return in tab later it has problems. To be more precise, it Incorrectly displays the time.
I'd also tried setTimeout, but problem was the same.
One idea, which I have is: HTML5 Web Workers...
But here is another problem... browsers support.
can someone help to solve this problem?
How can I write setInterval, which works properly,even when tab is not active
Use the Date object to calculate time. Don't rely on a timer firing when you ask it to (they are NOT real-time) because your only guarantee is that it'll not fire before you ask it to. It could fire much later, especially for an inactive tab. Try something like this:
function initTimer(periodInSeconds) {
var end = Date.now() + periodInSeconds * 1000;
var x = window.setInterval(function() {
var timeLeft = Math.floor((end - Date.now()) / 1000);
if(timeLeft < 0) { clearInterval(x); return; }
$('#div').html('00:' + (timeLeft < 10 ? '0' + timeLeft : timeLeft));
},200);
}
initTimer(10);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div"></div>
Note that by checking it more frequently we can make sure it's never off by too much.
JavaScript timers are not reliable, even when the tab is active. They only guarantee that at least as much time as you specified has passed; there is no guarantee that exactly that amount of time, or even anything close to it, has passed.
To solve this, whenever the interval fires, note what time it is. You really only need to keep track of two times: the current time, and the time that the previous interval fired. By subtracting the previous tick's time from the current tick's time, you can know how much time has actually passed between the two, and run your calculations accordingly.
Here's a basic outline of how something like this might look:
function initTimer(timeLeft) {
var Me = this,
TotalSeconds = 35,
Seconds = Math.floor(timeLeft),
CurrentTime = Date.now(),
PreviousTime = null;
var x = window.setInterval(function() {
var timer = Seconds,
timePassed;
PreviousTime = CurrentTime;
CurrentTime = Date.now();
timePassed = CurrentTime - PreviousTime;
if(timer < 0) { clearInterval(x); return; }
$('#div').html('00:' + (timer < 10 ? '0' + timer : timer));
Seconds = Seconds - timePassed;
},1000);
}

Check if specified time is mentioned in an incremented time

Here are some of the variables I have:
start time: 10:45
interval time: 5 (in minutes)
specific time: 14:20
I need to find out if the specific time lands exactly on any of the times incremented from the start time.
For example, the interval time is 5.
10:45 incremented by interval time
11:00
11:05
11:10
...
14:20 << specific time found
if(specificTime is mentioned in any of the incremented times) {
console.log('Found it!');
} else {
console.log('Not found');
}
But this is hard when the start time is 10:48 and the interval time is 5 minutes. Because:
10:48
10:53
10:58
11:03
11:08
...
and 14:20 is not mentioned in this one, so it would log "Not found".
How can I find out if the specific times is mentioned in the incremented times from the start time?
The interval time will not always be 5 and the other variables will be dynamic as well.
I am NOT looking to use loops. There has to be a formula or function that can help me achieve this. Thanks!
I think you can calculate if it is possible to perform a restless division of the difference between the start time and the specified time and the interval.
Depending on the scale of your time intervals, you can calculate this in hours, minutes, seconds, milliseconds or basically any scale. Since your examples deal in minutes, the code snippet also does.
Note that this snippet assumes both times are within the same day (00:00 - 24:00) and that the specific time is later within that day than the start time. I'll let you figure out the rest :)
function toMinutes(hours, minutes) {
return (hours * 60) + minutes;
}
const startTime = toMinutes(10, 45);
const specificTime = toMinutes(14, 20);
const interval = toMinutes(0, 5);
const difference = specificTime - startTime;
if (difference % interval === 0) {
console.info('Found it!');
console.info('Minutes:', difference);
console.info('Intervals:', difference / interval);
} else {
console.error('Not found');
}
This works by:
- Turning the time strings into numeric minutes (with countOfMinutes())
- Subtracting startTime from specificTime (and adjusting if we increment past 12:00)
- Dividing the result by minsPerIncrement and checking whether the remainder is zero
// The big payoff -- calculates whether we exactly hit `specificTime`
function isExact(start, specific, increment){
let difference = countOfMinutes(specific) - countOfMinutes(start);
if(difference <= 0){ difference += 12 * 60; } // Add 12 hours if necessary
return difference % increment == 0;
}
// The converter -- because numbers are easier to divide than strings
function countOfMinutes(timeString){
const hours = timeString.slice(0, timeString.indexOf(":"));
const mins = timeString.slice(timeString.indexOf(":") + 1);
return hours * 60 + mins;
}
// The results -- some readable output
function report(){
console.log(`
Repeatedly adding ${minsPerIncrement} to ${startTime} will eventually yield ${specificTime}?:
_ ${isExact(startTime, specificTime, minsPerIncrement)} _`);
}
// The pudding -- a couple of test cases
let start, specific, minsPerIncrement;
startTime = "12:30"; specificTime = "3:55"; minsPerIncrement = 21;
report();
startTime = "4:20"; specificTime = "11:45"; minsPerIncrement = 5;
report();
startTime = "11:45"; specificTime = "4:20"; minsPerIncrement = 5;
report();

Making a min:sec counter using javascript

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.

Categories