How to run a function at specific time & date? - javascript

How can I run a function at a given time and date?
Example: I have a function that needs to run on the 12th of each month at 10AM.
This page will be running 24/7, if this is important.
Obviously I'd have to compare against the current date, but I'm not sure how to check if the current date and time has been matched.
Shannon

It's not advised to use setInterval because it has non-deterministic behaviour - events can be missed, or fire all at once. Time will fall out of sync, too.
The code below instead uses setTimeout with a one minute period, where each minute the timer is resynchronised so as to fall as closely to the hh:mm:00.000s point as possible.
function surprise(cb) {
(function loop() {
var now = new Date();
if (now.getDate() === 12 && now.getHours() === 12 && now.getMinutes() === 0) {
cb();
}
now = new Date(); // allow for time passing
var delay = 60000 - (now % 60000); // exact ms to next minute interval
setTimeout(loop, delay);
})();
}

On the page where o want to do the check add this
setInterval(function () {
var date = new Date();
if (date.getDate() === 12 && date.getHours() === 10 && date.getMinutes === 0) {
alert("Surprise!!")
}
}, 1000)
FIDDLE
Update- add date.getSeconds == 0 to limit it to fire only one at 10:00:00. Thanks to comments below

You can instantiate two Date objects. One for now and one for the next instance of the event. Now is easy: new Date(). For the next instance you can loop through the options till you find one larger than now. Or do some more sophisticated date time wizardry. Compare the getTime() of the both, and then do a setTimeout for the alert.
EDIT:
Updated since #Alnitak points out that there's a maximum to the timeout, see setTimeout fires immediately if the delay more than 2147483648 milliseconds.
function scheduleMessage() {
var today=new Date()
//compute the date you wish to show the message
var christmas=new Date(today.getFullYear(), 11, 25)
if (today.getMonth()==11 && today.getDate()>25)
christmas.setFullYear(christmas.getFullYear()+1)
var timeout = christmas.getTime()-today.getTime();
if( timeout > 2147483647 ){
window.setTimeout( scheduleMessage(), 2147483647 )
} else {
window.setTimeout(function() {alert('Ho Ho Ho!'); scheduleMessage()}, timeout)
}
}

You can use something like this
var runned = false;
var d = new Date();
if(d.getDate() == 12 && d.getHours() == 10 && !runned){
//Do some magic
runned = true;
}
If you want some with the minute (and not the whole hour you can add d.getMinutes()

maybe use and iframe with meta refresh and workout content server side
<meta http-equiv="refresh" content="{CHANGE_THIS_TO_WHAT_YOU_CALCULATED_AT_SERVER}">
or use javascripts setInterval
var interval = 300000; // run in 5 minutes
window.setInterval("reloadRefresh();", interval);
function reloadRefresh() {
// do whatever
}
and

Related

JavaScript redirect to another page when time reaches 5 minutes to top of hour

I want to redirect a user to another page when the time reaches 5 minutes to the top of the hour.
In 24 hour time that means I want the redirect to run on intervals like this...
11:55
12:55
13:55
14:55
15:55
etc
So far all I can figure out is the "count down" style of JS redirection like this, but instead of that I need something that runs based on time (5 minutes to the top of the hour) not a count down.
setTimeout("location.href = 'https://www.google.com';",1000);
I have also tried this but nothing happened.
var mins = new Date().getMinutes();
if (mins == 55) {
window.location.href = "https://www.google.com";
}
Is this possible with JavaScript (or jQuery)?
You're close - you just need to calculate the time remaining from when the user loads the page. I would throw this in the document.ready callback if you're already using jQuery.
const interval = 55*60*1000 // 55 min in ms
const msUntilNext = interval - new Date().getTime() % interval;
const timeout = setTimeout(() => {
location.href = 'https://www.google.com';
}, msUntilNext)
setTimeout() happens after a specified amount of time, where you have it defined to fire after 1 second (1000 milliseconds = 1 second) and then it will stop, unless you trigger the timeout again.
One solution is to check the timeout every 1 second using setInterval, and as soon as the minutes reach 55 minutes, do the redirect. You could also change this to trigger less frequently, say every 15 or 30 seconds (15000, 30000).
// function that triggers at the interval
function checkTimeout() {
var now = new Date();
var minutes = now.getMinutes();
console.log(minutes);
if (minutes >= 55) {
location.href = 'https://www.google.com';
}
}
setInterval(checkTimeout, 1000); // check interval every 1 second

Updating time without refreshing the page with Javascript

I'm building an app that displays the current time without have to refresh.
I'm calling the time below, but when I display it I have to refresh the page to update the time. How do I continuously update the time?
function GetTime(){
var today = new Date();
var hour = today.getHours();
var minute = today.getMinutes();
if (hour>=12){ //Adding endings
suffix = "P.M.";}
else{
suffix = "A.M.";}
minute = addZero(minute); //Call addZero function
hour = removeMilitary(hour); //Call removeMilitary Function
var fullTime = hour + ":" + minute + " " + suffix; //Combine hour minute and the suffix
function addZero(number){
if (number<10){
number = "0" + number;
}
return number;
}
function removeMilitary(hour){ //This function can be removed if desired by user.
if (hour > 0 && hour <= 12) {
hour = "" + hour;
} else if (hour > 12) {
hour = "" + (hour - 12);
} else if (hour == 0) {
hour= "12";
}
return hour;
}
return fullTime;
}
Javascript has a setInterval method.
You can get the time every second, by running your program every 1000 milliseconds:
setInterval(GetTime, 1000);
//if you incorporate updating the html
//within the getTime function
or
setInterval(function(){
document.getElementById("ID_of_the_time_element").innerHTML= getTime();
//do something else
}, 1000}
Why setInterval at 1000 ms isn't very accurate
The problem with that is unless you start the set interval exactly on the second, your program will not change the second exactly on the second. I would recommend you get it more accurate by adjusting the interval to every 100 ms, for example. Then it would update every 100ms, which means that the most your clock will be behind is a tenth of a second.
A better solution
Setting an interval every 100ms is ok, but if you want more accuracy, setting it to 10ms isn't necessarily the best option, because repeating a task every 10ms is a pretty large burden on the computer. You could also use find the number of ms until the next second, and then use the setTimeout method to wait until the next second arrives and start the set timeout then. You would still have some computational delay(the amount of time between when it gets the number of milliseconds until the next second and it starts the setTimeout), but that's probably a lot less than 100 ms.
I assume you will use the setInterval() function.
just add this to your button onclick;
setInterval(function(){Document.getElementById("div").innerHTML = getTime},1000);
setInterval (GetTime, 1000) will call your function every second (1000 milliseconds) to get the time. You don't show how you're putting the time on the page, so you'll need to incorporate that as well.
UPDATE I forgot the setInterval but someone else already pointed at it, so mix both answers and you're done!
Look at getElementById and innerHTML.
Something like the following snippet at the end of your function (instead of return fulltime ) should work:
...
var myElement = documentGetElementById('mydiv');
myElement.innerHTML = fulltime;
...
Of course you need to define some HTML element with <div id="mydiv"></div> or whatever you choose.

Script to run function at specific time with milliseconds

I have that code at below, how can I run it at 21:36:00:500 (500 is milliseconds) ?
var now = new Date();
var millisTill1 = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 45, 30, 500) - now;
if (millisTill1 < 0) {
millisTill1 += 86400000;
}
setTimeout(function() {
check()
}, millisTill1);
I have tested this code for 1 minute timer execution it works. Also it just adds to the time limit after which it executes once. Kindly consider this code.
tDate = new Date();
tDate.setHours(21);
tDate.setMinutes(36);
tDate.setSeconds(0);
tDate.setMilliseconds(500);
tMillis = tDate - new Date();
if (tMillis < 0)
tMillis = tMillis + 24 * 60 * 60 * 1000; // if time is greater than 21:36:00:500 just add 24 hours as it will execute next day
setTimeout(function() {
console.log('Execute');
}, tMillis)
You can validate the code by using 1 minute ahead timer to confirm the output.
You can't do it with setTimeout. setTimeout function requires you to pass a second parameter (called millisTill1 in your example) in milliseconds.
Most browsers, have a bottom threshold of 10ms, which means you can't go below 10000 microseconds or 0.01s.
While JS is not suitable for this, most common task that would get you where you need to go would most probably use setInterval and look like:
(setInterval(function() {
var currentTime = new Date();
if (
currentTime.getHours() === 1 &&
currentTime.getMinutes() === 38 &&
currentTime.getSeconds() === 0 &&
currentTime.getMilliseconds() === 500
) {
// your code
}
}, 500))();
This one would check the time each time a pollingTime interval passes. Most commonly this would be 1 minute (60000). You can go lower, but risk performance issues. Don't forget javascript runs on the client. If you would use setTimeout time would be checked only once and your script would stop.
If you need to execute something, better use a combination of system scheduler like Task Scheduler on Windows or Automator on OSX with a scripting language like bash or python.

How can i make something happen in a time range?

I want a box to popup at 14:00. Later i want it to disappear at 16:00. How can i do this? I am using Android Studio. I want it to be something like this:
if (Calendar.HOUR_OF_DAY > 14) {
Log.d("TIME", "Time Works!");
}
I'm unsure about Android Studio, but for JavaScript alone, you can use the setTimeout() function to invoke some task every X amount of time. Set this up to check the current time every once in a while, and if it's more than 14:00 and less than 16:00, make sure your popup is shown, otherwise close it...
setTimeout(handlePopupVisibility, 60000);
function handlePopupVisibility() {
var now = new Date();
var startTime = dateObj('2:00 PM');
var endTime = dateObj('4:00 PM');
if (now < dateEnd && now > startTime) {
// inside the range, show your element
// (assumes jQuery)
$("#popupID").show();
} else {
// outside the range, hide your element
// (assumes jQuery)
$("#popupID").hide();
}
}
function dateObj(d) {
var parts = d.split(/:|\s/),
date = new Date();
if (parts.pop().toLowerCase() == 'pm') parts[0] = (+parts[0]) + 12;
date.setHours(+parts.shift());
date.setMinutes(+parts.shift());
return date;
}
(stolen from answer here: How to check if current time falls within a specific range considering also minutes )

In JavaScript, how can I have a function run at a specific time?

I have a website that hosts a dashboard: I can edit the JavaScript on the page and I currently have it refreshing every five seconds.
I am trying to now get a window.print() to run every day at 8 AM.
How could I do this?
JavaScript is not the tool for this. If you want something to run at a specific time every day, you're almost certainly looking for something that runs locally, like python or applescript.
However, let's consider for a moment that JavaScript is your only option. There are a few ways that you could do this, but I'll give you the simplest.
First, you'll have to to create a new Date() and set a checking interval to see whether the hour is 8 (for 8 AM).
This will check every minute (60000 milliseconds) to see if it is eight o'clock:
window.setInterval(function(){ // Set interval for checking
var date = new Date(); // Create a Date object to find out what time it is
if(date.getHours() === 8 && date.getMinutes() === 0){ // Check the time
// Do stuff
}
}, 60000); // Repeat every 60000 milliseconds (1 minute)
It won't execute at exactly 8 o'clock (unless you start running this right on the minute) because it is checking once per minute. You could decrease the interval as much as you'd like to increase the accuracy of the check, but this is overkill as it is: it will check every minute of every hour of every day to see whether it is 8 o'clock.
The intensity of the checking is due to the nature of JavaScript: there are much better languages and frameworks for this sort of thing. Because JavaScript runs on webpages as you load them, it is not meant to handle long-lasting, extended tasks.
Also realize that this requires the webpage that it is being executed on to be open. That is, you can't have a scheduled action occur every day at 8 AM if the page isn't open doing the counting and checking every minute.
You say that you are already refreshing the page every five seconds: if that's true, you don't need the timer at all. Just check every time you refresh the page:
var date = new Date(); // Create Date object for a reference point
if(date.getHours() === 8 && date.getMinutes() === 0 && date.getSeconds() < 10){ // Check the time like above
// Do stuff
}
With this, you also have to check the seconds because you're refreshing every five seconds, so you would get duplicate tasks.
With that said, you might want to do something like this or write an Automator workflow for scheduled tasks on OS X.
If you need something more platform-agnostic, I'd seriously consider taking a look at Python or Bash.
As an update, JavaScript for Automation was introduced with OS X Yosemite, and it seems to offer a viable way to use JavaScript for this sort of thing (although obviously you're not using it in the same context; Apple is just giving you an interface for using another scripting language locally).
If you're on OS X and really want to use JavaScript, I think this is the way to go.
The release notes linked to above appear to be the only existing documentation as of this writing (which is ~2 months after Yosemite's release to the public), but they're worth a read. You can also take a look at the javascript-automation tag for some examples.
I've also found the JXA Cookbook extremely helpful.
You might have to tweak this approach a bit to adjust for your particular situation, but I'll give a general overview.
Create a blank Application in Automator.
Open Automator.app (it should be in your Applications directory) and create a new document.
From the dialog, choose "Application."
Add a JavaScript action.
The next step is to actually add the JavaScript that will be executed. To do that, start by adding a "Run JavaScript" action from the sidebar to the workflow.
Write the JavaScript.
This is where you'll have to know what you want to do before proceeding. From what you've provided, I'm assuming you want to execute window.print() on a page loaded in Safari. You can do that (or, more generally, execute arbitrary JS in a Safari tab) with this:
var safari = Application('Safari');
safari.doJavaScript('window.print();', { in: safari.windows[0].currentTab });
You might have to adjust which of the windows you're accessing depending on your setup.
Save the Application.
Save (File -> Save or ⌘+S) the file as an Application in a location you can find (or iCloud).
Schedule it to run.
Open Calendar (or iCal).
Create a new event and give it an identifiable name; then, set the time to your desired run time (8:00 AM in this case).
Set the event to repeat daily (or weekly, monthly, etc. – however often you'd like it to run).
Set the alert (or alarm, depending on your version) to custom.
Choose "Open file" and select the Application file that you saved.
Choose "At time of event" for the alert timing option.
That's it! The JavaScript code that you wrote in the Application file will run every time that event is set to run. You should be able to go back to your file in Automator and modify the code if needed.
function every8am (yourcode) {
var now = new Date(),
start,
wait;
if (now.getHours() < 7) {
start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0, 0);
} else {
start = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 8, 0, 0, 0);
}
wait = start.getTime() - now.getTime();
if(wait <= 0) { //If missed 8am before going into the setTimeout
console.log('Oops, missed the hour');
every8am(yourcode); //Retry
} else {
setTimeout(function () { //Wait 8am
setInterval(function () {
yourcode();
}, 86400000); //Every day
},wait);
}
}
To use it:
var yourcode = function () {
console.log('This will print evryday at 8am');
};
every8am(yourcode);
Basically, get the timestamp of now, the timestamp of today 8am if run in time, or tomorrow 8am, then set a interval of 24h to run the code everyday. You can easily change the hour it will run by setting the variable start at a different timestamp.
I don t know how it will be useful to do that thought, as other pointed out, you ll need to have the page open all day long to see that happen...
Also, since you are refreshing every 5 seconds:
function at8am (yourcode) {
var now = new Date(),
start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 8, 0, 0, 0);
if (now.getTime() >= start.getTime() - 2500 && now.getTime() < start.getTime() + 2500) {
yourcode();
}
}
Run it the same way as every8am, it look if 8am is 2.5second ahead or behind, and run if it does.
I try to give my answer hoping it could help:
function startJobAt(hh, mm, code) {
var interval = 0;
var today = new Date();
var todayHH = today.getHours();
var todayMM = today.getMinutes();
if ((todayHH > hh) || (todayHH == hh && todayMM > mm)) {
var midnight = new Date();
midnight.setHours(24,0,0,0);
interval = midnight.getTime() - today.getTime() +
(hh * 60 * 60 * 1000) + (mm * 60 * 1000);
} else {
interval = (hh - todayHH) * 60 * 60 * 1000 + (mm - todayMM) * 60 * 1000;
}
return setTimeout(code, interval);
}
With the startJobAt you can execute only one the task you wish, but if you need to rerun your task It's up to you to recall startJobAt.
bye
Ps
If you need an automatic print operation, with no dialog box, consider to use http://jsprintsetup.mozdev.org/reference.html plugin for mozilla or other plugin for other bowsers.
I will suggest to do it in Web Worker concept, because it is independent of other scripts and runs without affecting the performance of the page.
Create a web worker (demo_worker.js)
var i = 0;
var date = new Date();
var counter = 10;
var myFunction = function(){
i = i + 1;
clearInterval(interval);
if(date.getHours() === 8 && date.getMinutes() === 0) {
counter = 26280000;
postMessage("hello"+i);
}
interval = setInterval(myFunction, counter);
}
var interval = setInterval(myFunction, counter);
Use the web worker in Ur code as follows.
var w;
function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(w) == "undefined") {
w = new Worker("demo_worker.js");
w.onmessage = function(event) {
window.print();
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support HTML5 Web Workers";
}
}
}
I think it will help you.
I have written function which
allows expressing delay in seconds, new Date() format and string's new Date format
allows cancelling timer
Here is code:
"use strict"
/**
This function postpones execution until given time.
#delay might be number or string or `Date` object. If number, then it delay expressed in seconds; if string, then it is parsed with new Date() syntax. Example:
scheduleAt(60, function() {console.log("executed"); }
scheduleAt("Aug 27 2014 16:00:00", function() {console.log("executed"); }
scheduleAt("Aug 27 2014 16:00:00 UTC", function() {console.log("executed"); }
#code function to be executed
#context #optional `this` in function `code` will evaluate to this object; by default it is `window` object; example:
scheduleAt(1, function(console.log(this.a);}, {a: 42})
#return function which can cancel timer. Example:
var cancel=scheduleAt(60, function(console.log("executed.");});
cancel();
will never print to the console.
*/
function scheduleAt(delay, code, context) {
//create this object only once for this function
scheduleAt.conv = scheduleAt.conv || {
'number': function numberInSecsToUnixTs(delay) {
return (new Date().getTime() / 1000) + delay;
},
'string': function dateTimeStrToUnixTs(datetime) {
return new Date(datetime).getTime() / 1000;
},
'object': function dateToUnixTs(date) {
return date.getTime() / 1000;
}
};
var delayInSec = scheduleAt.conv[typeof delay](delay) - (new Date().getTime() / 1000);
if (delayInSec < 0) throw "Cannot execute in past";
if (debug) console.log('executing in', delayInSec, new Date(new Date().getTime() + delayInSec * 1000))
var id = setTimeout(
code,
delayInSec * 1000
);
//preserve as a private function variable setTimeout's id
return (function(id) {
return function() {
clearTimeout(id);
}
})(id);
}
Use this as follows:
scheduleAt(2, function() {
console.log("Hello, this function was delayed 2s.");
});
scheduleAt(
new Date().toString().replace(/:\d{2} /, ':59 '),
function() {
console.log("Hello, this function was executed (almost) at the end of the minute.")
}
);
scheduleAt(new Date(Date.UTC(2014, 9, 31)), function() {
console.log('Saying in UTC time zone, we are just celebrating Helloween!');
})
setInterval(() => {
let t = `${new Date().getHours() > 12 ? new Date().getHours() - 12 : new Date().getHours()}:${new Date().getMinutes().length < 2 ? '0' + new Date().getMinutes() : new Date().getMinutes()}:${new Date().getSeconds().length < 2 ? '0' + new Date().getSeconds() : new Date().getSeconds()} ${new Date().getHours()>12?"pm":"am"}`
console.log(t);
}, 1000);

Categories