I have written a JavaScript function that I simply copy paste into a browser console and runs, all works great and is working exactly as I want it to.
Looks like:
function test(d) {
// ....
}
test(num);
I'm looking to wrap this function with kind of like a "while" statement. Please do keep in mind I'm not the greatest with JavaScript, yet.
Basically, What I'm looking for is while its NOT 6:30PM EST... keep waiting and check again. The second it hits 6:30 PM EST, execute the script.
Can anyone help me with what the syntax would look like? I found a lot on Stack Overflow but the syntax isn't really making sense to me.
Any help would be greatly appreciated.
Okay, a couple of notes. If you're not required to run a script in the browser itself but simply run some JavaScript at specific intervals you should checkout some schedulers like cron and more specifically for JavaScript - node-cron.
A solution which revolves around checking "is it time, is it time,..." each second or so in a loop is a pretty bad way to do it.
It is highly wasteful and poorly performant.
It will block your script execution so you have to execute it in a separate process like a web worker.
The simplest way, without using any dependencies is to schedule your work manually using a combination of setTimeout and setInterval. Here is a pretty basic and unpolished solution which should get you going.
const msInSecond = 1000;
const msInMinute = 60 * msInSecond;
const msInHour = 60 * msInMinute;
const msInDay = 24 * msInHour;
const desiredTimeInHoursInUTC = 18; // fill out your desired hour in UTC!
const desiredTimeInMinutesInUTC = 30; // fill out your desired minutes in UTC!
const desiredTimeInSecondsInUTC = 0; // fill out your desired seconds in UTC!
const currentDate = new Date();
const controlDate = new Date(currentDate.getUTCFullYear(), currentDate.getUTCMonth(), currentDate.getUTCDate(), desiredTimeInHoursInUTC, desiredTimeInMinutesInUTC, desiredTimeInSecondsInUTC);
let desiredDate;
if (currentDate.getTime() <= controlDate.getTime()) {
desiredDate = controlDate;
}
else {
desiredDate = new Date(controlDate.getTime() + msInDay);
}
const msDelta = desiredDate.getTime() - currentDate.getTime();
setTimeout(setupInterval, msDelta);
function setupInterval() {
actualJob();
setInterval(actualJob, msInDay);
}
function actualJob() {
console.log('test');
}
In short, it calculates the difference between the current time and the next possible upcoming time slot for execution. Then, we use this time difference to execute the desired task and further schedule executions on every 24h after that.
You need to provide values for desiredTimeInHoursInUTC, desiredTimeInMinutesInUTC and desiredTimeInSecondsInUTC. All of them should be in UTC (the normal difference between EST and UTC is -4 or in other words - (hour EST - hour UTC = -4). You can (and actually should) improve this solution to handle timezones and the time difference calculations in general more elegantly.
A caveat here is that it won't handle daylight saving for you so you should keep that in mind. You can tackle this easily by using a dedicated library like moment.js. Also, the code is simple and in this version doesn't support cases like skipping specific days and such. You can always extend it to handle those, though.
Lastly, every time you restart the script, it will schedule your function execution times properly so you don't need to keep your tab open at all times. As an added benefit, the solution is quite performant as it doesn't do checks continuously if the time for execution has come but schedules everything in advance and doesn't do any more checks after that.
Related
I'm fairly new to javascript and programming at all, to be honest. I know html and css and the basics of javascript and I'm trying to figure out how time works in js.
I would like to make a simple game where the user can take care of a horse. And every action he does (i.e brushing the mane) would take a specific amount of time. Let's say five minutes for that. How do I code that?
Would be really thankful if anyone could tell me. Thank you in advance.
Jolly
just get the time in the future when the even would be finished at.
use this function
function getTime(numOfHours) {
let date = new Date();
date.setTime(date.getTime() + numOfHours * 60 * 60 * 1000);
return date;
}
then do check in your game logic to see if the event end time against the current time.
let endEventTime = getTime(0,00138); // add 5 seconds to the current time
// do a loop or some setTimeout() login and once the time passes then let your user do another action.
How can I create a Node.JS accurate timer? I am trying to make a chess website where you can play against other players on time.
I am currently using setInterval() and am not sure how accurate that is. I also need some extra accurate timer for the server that should be able to check in a 100th of a second precision can tell if the move is in time and when the game has ended.
Thanks in advance
For ordinary time-of-day, Date.now() gives you the date and time in milliseconds as a Javascript number. It has millisecond resolution. Its precision depends on your underlying operating system, but is typically between 10 and 50 milliseconds.
You can use process.hrtime.bigint(), described here, to retrieve the number of nanoseconds elapsed in nanoseconds.
Like this:
const then = process.hrtime.bigint()
/* do something you want to measure */
const now = process.hrtime.bigint()
const elapsedTimeInSeconds = (now-then) / 1_000_000_000
But be aware of this. Date.now() gives you a number of milliseconds since the UNIX epoch so it can be used to represent calendar dates and clock times. process.hrtime.bigint() gives you the number of nanoseconds since some arbitrary start time in the recent past. So it's only really useful for measuring elapsed times within nodejs processes.
And, I'm sure you're aware of single threading in Javascript, so elapsed time doesn't equal CPU time unless you don't do any sort of await operation in the code you're measuring.
You could also try to use `process.cpuUsage(), described here. Something like this.
const then = process.cpuUsage()
/* do something you want to measure */
const now = process.cpuUsage(then)
const userTimeInSeconds = (now.user - then.user) / 1_000_000
const systemTimeInSeconds = (now.system - then.system) / 1_000_000
Explaining the difference between user and system CPU time is beyond the scope of a Stack Overflow answer, but you can read about it.
I got this code over here:
var date = new Date();
setTimeout(function(e) {
var currentDate = new Date();
if(currentDate - date >= 1000) {
console.log(currentDate, date);
console.log(currentDate-date);
}
else {
console.log("It was less than a second!");
console.log(currentDate-date);
}
}, 1000);
In my computer, it always executes correctly, with 1000 in the console output. Interestedly in other computer, the same code, the timeout callback starts in less than a second and the difference of currentDate - date is between 980 and 998.
I know the existence of libraries that solve this inaccuracy (for example, Tock).
Basically, my question is: What are the reasons because setTimeout does not fire in the given delay? Could it be the computer that is too slow and the browser automatically tries to adapt to the slowness and fires the event before?
PS: Here is a screenshot of the code and the results executed in the Chrome JavaScript console:
It's not supposed to be particularly accurate. There are a number of factors limiting how soon the browser can execute the code; quoting from MDN:
In addition to "clamping", the timeout can also fire later when the page (or the OS/browser itself) is busy with other tasks.
In other words, the way that setTimeout is usually implemented, it is just meant to execute after a given delay, and once the browser's thread is free to execute it.
However, different browsers may implement it in different ways. Here are some tests I did:
var date = new Date();
setTimeout(function(e) {
var currentDate = new Date();
console.log(currentDate-date);
}, 1000);
// Browser Test1 Test2 Test3 Test4
// Chrome 998 1014 998 998
// Firefox 1000 1001 1047 1000
// IE 11 1006 1013 1007 1005
Perhaps the < 1000 times from Chrome could be attributed to inaccuracy in the Date type, or perhaps it could be that Chrome uses a different strategy for deciding when to execute the code—maybe it's trying to fit it into the a nearest time slot, even if the timeout delay hasn't completed yet.
In short, you shouldn't use setTimeout if you expect reliable, consistent, millisecond-scale timing.
In general, computer programs are highly unreliable when trying to execute things with higher precision than 50 ms. The reason for this is that even on an octacore hyperthreaded processor the OS is usually juggling several hundreds of processes and threads, sometimes thousands or more. The OS makes all that multitasking work by scheduling all of them to get a slice of CPU time one after another, meaning they get 'a few milliseconds of time at most to do their thing'.
Implicity this means that if you set a timeout for 1000 ms, chances are far from small that the current browser process won't even be running at that point in time, so it's perfectly normal for the browser not to notice until 1005, 1010 or even 1050 milliseconds that it should be executing the given callback.
Usually this is not a problem, it happens, and it's rarely of utmost importance. If it is, all operating systems supply kernel level timers that are far more precise than 1 ms, and allow a developer to execute code at precisely the correct point in time. JavaScript however, as a heavily sandboxed environment, doesn't have access to kernel objects like that, and browsers refrain from using them since it could theoretically allow someone to attack the OS stability from inside a web page, by carefully constructing code that starves other threads by swamping it with a lot of dangerous timers.
As for why the test yields 980 I'm not sure - that would depend on exactly which browser you're using and which JavaScript engine. I can however fully understand if the browser just manually corrects a bit downwards for system load and/or speed, ensuring that "on average the delay is still about the correct time" - it would make a lot of sense from the sandboxing principle to just approximate the amount of time required without potentially burdening the rest of the system.
Someone please correct me if I am misinterpreting this information:
According to a post from John Resig regarding the inaccuracy of performance tests across platforms (emphasis mine)
With the system times constantly being rounded down to the last queried time (each about 15 ms apart) the quality of performance results is seriously compromised.
So there is up to a 15 ms fudge on either end when comparing to the system time.
I had a similar experience.
I was using something like this:
var iMillSecondsTillNextWholeSecond = (1000 - (new Date().getTime() % 1000));
setTimeout(function ()
{
CountDownClock(ElementID, RelativeTime);
}, iMillSecondsTillNextWholeSecond);//Wait until the next whole second to start.
I noticed it would Skip a Second every couple Seconds, sometimes it would go for longer.
However, I'd still catch it Skipping after 10 or 20 Seconds and it just looked rickety.
I thought, "Maybe the Timeout is too slow or waiting for something else?".
Then I realized, "Maybe it's too fast, and the Timers the Browser is managing are off by a few Milliseconds?"
After adding +1 MilliSeconds to my Variable I only saw it skip once.
I ended up adding +50ms, just to be on the safe side.
var iMillSecondsTillNextWholeSecond = (1000 - (new Date().getTime() % 1000) + 50);
I know, it's a bit hacky, but my Timer is running smooth now. :)
Javascript has a way of dealing with exact time frames. Here’s one approach:
You could just save a Date.now when you start to wait, and create an interval with a low ms update frame, and calculate the difference between the dates.
Example:
const startDate = Date.now()
setInterval(() => {
const currentDate = Date.now()
if (currentDate - startDate === 1000 {
// it was a second
clearInterval()
return
}
// it was not a second
}, 50)
My processor runs at 2.0 GHz.
I have a new computer with as much software removed as possible except my development tools. This system is clean with no malware.
When I run the code below I get about 2M loops per second. That is about 1 MHz.
Suppose doing and addition, and doing a compare takes 10x the simplest operation, I get about 10 MHz
Why do I not get more utilization of my processor?
var Utility =
{
time: function()
{
var end_time,
start_time,
index = 0;
start_time = new Date().getTime();
while ( index <= 1000000 )
{
index++;
}
end_time = new Date().getTime();
return ( end_time - start_time);
}
};
This is not really about JavaScript - it's more about the browser and the way it's handling JavaScript.
Each browser is doing this differently, but most modern browsers won't let JavaScript take 100% of the resources to prevent the client machine from crashing.
Bottom line you can't do such thing with client side scripting, you'll have to use "real" application with full access to the computer.
Suppose doing and addition, reading a clock, and doing a compare takes
100x the simplest operation (very conservative), I get (.1MHz * 100) =
1MHz.
This is not how computers work and measuring speed like this is not going to get you anywhere. Besides, it depends a lot on the JavaScript engine being used. I heard a lot of good things about the V8 JS engine that Chrome uses, Opera's seems to be pretty fast too.
So try it with different browsers to get a real comparison. But if you want to measure how much time it took to do some operation (pseudo code):
var start = get_current_time();
// do the complex operation
var end = get_current_time ();
var time_it_took = end - start;
The time functions should have as small a granularity as possible.
Well for one thing you would be creating a new date object every time thorugh the loop -- why not create the date object for comparision before you enter the loop?
I have from the backend a time on the format 00:12:54 and I display it to the screen. But, I would like to have this time to continue to go down. I have though to create a variable in javascript that will old the time and with setTimeout to loop to display with document.getElementById the new value. I think it can be problematic if I have many time to go down in same time. I might require an array?
How would you do that? If I have no other suggestion, I will try my way, but I am curious to know if it does have a more secure way to do it.
Do you know jQuery Framework? It's a Javascript framework that have a lot of utilities methods and functions that let you do Javascript stuff more easily.
Here is a count down plugin (haven't tested it).
I suggest you to download JQuery than download the plugin . Check the sample of code from the "relative" tab on the website. You can have something like :
$('#until2d4h').countdown({until: '+12M +54S'});
*The only drawback with what I suggest you is that you will require 2 .js to be added. Try to add them only when needed and you will be find.
General algorithm:
Read time from server.
Read the current time.
Call a function.
In your function, read the current time, get the delta from the initial time you read in step 2.
Subtract the delta from the initial time you read from the server in step 1 and display the remainder.
The function should call window.setTimeout to call itself in 1000ms (or adjust according to time elapsed within the function), if you want to continue counting down.
Here's a rough cut:
window.onload = function () {
var countdown_start_in_ms = 6000; // from server
function tick() {
var now = new Date().getTime();
var disp = start - now;
if (disp < 0) {
disp = 0;
}
var el = document.getElementById("countdown");
el.innerHTML =
// quick hack to format time
/(\d\d:\d\d:\d\d) ...$/.exec(new Date(disp).toUTCString())[1];
if (disp > 1000) {
var elapsed = new Date().getTime() - now;
window.setTimeout(tick, 1000 - elapsed);
} else {
// stop countdown and set color to light grey
el.style.color = "#ccc";
}
}
var start = new Date().getTime() + countdown_start_in_ms;
tick();
}
You won't like the taste of this one, but it'll do you good:
Google for 'javascript timer' and get your hands dirty reading through the various examples and tutorials returned by that search.
You'll learn a lot more than just how to write a count-down timer. :-)
Good luck!
Take a look at Grab hands and set your own time. and inspect its code. While it is written with Dojo, the "clock" part is in plain JavaScript. In your case the only difference is how to advance the counter — decrease rather than increase it.