I need a running timer and checker - javascript

I am trying to create a function/alg that executes a script depending on the time.
This won't work with PHP's 'sleep' function (I've nested loops with headers and tried).
here is the logic I am seeking to accomplish:
$time= time(); // checks time
if($time == 3'o'clock) {
do_something();
} else {
check_time();
and_keep_counting();
}
I need a continous clock ticking | which can run in the background
at the same time, continous checking of the clock.
I may have to go jquery?

This will not be very efficient, but will do the trick:
(function time(){
var t = new Date().toLocaleTimeString();
console.log(t);
if(t === "3:00:00 PM"){
// Do whatever you need to here
runStuff();
}
// Call the function again in 59 seconds
setTimeout(time, 59000);
}());
function runStuff(){
alert("Time's Up!");
}

I'm not entirely sure what you're asking, but you can do something like this with JavaScript...
var date = new Date(); which creates a date-time object
var hours = date.getHours(); which gets the hours in "military time" format, meaning 1 is 1:00AM and 13 is 1:00PM
If you want to check if it's three o'clock, you can do
if (hours == 15) {
someFunction();
} else {
doSomeOtherFunction();
}

Related

Best Way to detect midnight and reset data

I've been developing a web application Dashboard and I was wondering how to detect that is midnight in order to reset some arrays that contains datas from the previous day using jquery or momentjs.
Use moment().format("h:mm:ss") that returns time in a h:mm:ss format.
var midnight = "0:00:00";
var now = null;
setInterval(function () {
now = moment().format("H:mm:ss");
if (now === midnight) {
alert("Hi");
}
$("#time").text(now);
}, 1000);
JSFIDDLE
A better way would be to compute the seconds until midnight. This is very simple and human readable using MomentJS:
// returns the number of seconds until next midnight
moment("24:00:00", "hh:mm:ss").diff(moment(), 'seconds');
So, just do:
setTimeout(
midnightTask,
moment("24:00:00", "hh:mm:ss").diff(moment(), 'seconds')
);
function midnightTask() {
/* do something */
}
JSFIDDLE
There's only really two ways to accomplish this
poll every x seconds and see whether we're within x seconds of midnight
Calculate the time between now and midnight, and sleep for that amount of time before executing
(1) has been demonstrated in other answers, here's (2).
The first thing to do is calculate the number of milliseconds until midnight then use that as a parameter to javascripts setTimeout.
setTimeout(function(){
// whatever you want to do at midnight
}, msToMidnight);
After you've finished your work in that function, you might want to recaculate the time until next midnight and repeat the process.
So I think you're going about this the wrong way. What you're looking for isn't when it's midnight, you just want to know when the day has changed, which is a much simpler task.
The first thing I'm going to say is avoid using timers at all costs. They're not worth it. The performance hit and extra CPU time you take from running the same function >3600 times a day is ridiculous, especially when it's running on someone else's computer. You don't know how much it can handle, so assume it can't handle much at all. Go easy on your users.
I would suggest listening to a user input event, assuming that this is something you would have on a regular computer, and not something like this, where there is no user input.
If user input events are something you could rely on, I would do this..
var today = new Date(), lastUpdate;
window.addEventListener( "mousemove", function () {
var time = new Date();
// If we haven't checked yet, or if it's been more than 30 seconds since the last check
if ( !lastUpdate || ( time.getTime() - lastUpdate.getTime() ) > 30000 ) {
// Set the last time we checked, and then check if the date has changed.
lastUpdate = time
if ( time.getDate() !== today.getDate() ) {
// If the date has changed, set the date to the new date, and refresh stuff.
today = time
this_is_where_you_would_reset_stuff()
}
}
} )
If you absolutely need to use a timer, then I would do this..
function init() {
var today = new Date();
var midnight = new Date();
midnight.setDate( today.getDate() + 1 )
midnight.setHours( 0 )
midnight.setMinutes( 0 )
setTimeout( function () {
// If the date has changed, set the date to the new date, and refresh stuff.
today = time
this_is_where_you_would_reset_stuff()
init()
}, midnight.getTime() - today.getTime() )
}
init()
Keep in mind that the second way is likely to be far less reliable.
Create a date at midnight this morning, add 86400 seconds, and set a timeout for then:
new Date(Date.parse((new Date()).toString().replace(/\d\d:\d\d:\d\d/,'00:00:00')) + 86400 * 1000)
Here's how you'd use it:
var delay_to_midnight = Date.parse((new Date()).toString().replace(/\d\d:\d\d:\d\d/,'00:00:00')) + 86400 * 1000 - Date.now()
var timeoutid = window.setTimeout(function() { alert("It's midnight!"); }, delay_to_midnight);
I would try:
window.setInterval(resetAtMidnight, 1000*5) // every five seconds
function resetAtMidnight() {
var now = new Date();
if(now.getHours() < 1
&& now.getMinutes() < 1
&& now.getSeconds() < 5 ) {
redrawPage();
}
};

Cannot print message according to time

I've three different times, two of them are in string forms (time1 and time2) and one from system date currDate. Next step according to the one of two above times I want to print messages when the system date reaches one of them. For this I've function callEachMinute that calls each minute to get system time (but here in code I did not include the whole procedure). Here is the current status of the code:
Script:
function callEachMinute() {
var currDate = new Date();
var time_1 = '8:30';
var time_2 = '23:00';
timeComparison(currDate, time_1, time_2)
}
function timeComparison(currTime, time1, time2) {
// Time 1 formatting
var t1 = new Date();
var parts1 = time1.split(":");
t1.setHours(parts1[0],parts1[1]);
// Iftor-Time formatting
var t2 = new Date();
var parts2 = timeI.split(":");
t2.setHours(parts2[0],parts2[1]);
/* Notification procedure */
if (currTime == t1) {
// Message for Time1
alert("Time 1 is reached");
}
if (currTime == t2) {
// Message for Time2
alert("Time 2 is reached");
}
}
Problem:
When the system time is reached one of times (time1 or time2) nothing happens. Any solution for this problem?
There are a few things that could be problematic here.
You set up a Date object then want to compare it to currTime:
if (currTime == t1) {
unfortunatley Javascript's == operator when applied to objects compares two objects to see if they are references to the same object, so even if currTime and t1 contained exactly the same time this check would evaluate to false since they are different instances. You could do this by converting to a string:
if (currTime.toString() == t1.toString) {
which would work if the string representations for each data work out the same.
However, a more straight forward approach might be to tackle this the other way around - extract the hours and minutes from currTime, build a string and compare that to your time strings. Something like:
// in timecomparison function
var hrs = currTime.getHours();
var mins = currTime.getMinutes();
var now = hrs+":"+mins
// now do comparisons
if (now == time1 ) {
....
}
and so on.

Performing an operation days or months in the future

I'm trying to figure out the best way to perform a task, e.g. send an email to a user, in the future.
My idea is to store (in a database along with users data) when the email needs to be sent, and on a daily basis check what users need emails sent, and use Meteor's Timer functions.
// 7 hours in millisec.
Meteor.setTimeout( function() {
Meteor.call( "sendReminderEmail", ... );
}, 2.52e+7 );
The problem that I see is having too many timers set up, and hindering performance. What is a good solution?
Edit: Basically my use case includes the user creating an event, which they set as a long term event or short term(based on days, weeks, or months), and they receive a follow-up on that event depending on the duration.
I guess I could check every hour, but that seems like a problem with equal cost. Is there a Meteor specific way to do this? Or just a better concept?
Edit2: Ok, I've realized that accurracy isn't that important for my problem, so I'm thinking of setting one timer per timezone, which would send bulk emails. If the user has a long term event and their reminder is this week, than send it now. Basically it depends on duration of event and timezone of user.
So my updated question is, how do I run something on a daily basis, with my problem in mind?
Let's say you want to execute a code at 9am today and now is 8am, you could create a timeout to match the minutes in the targeted time and then create a interval of 1 hour and at each execution check if the time is 9am, if it's, execute.
in this small scale example, I'm executing executeMe() when the clock shows 9 seconds:
Live Test: http://jsbin.com/ikulok/4/edit
<body>
Last run: <span id="time"></span><br>
Next execution: <span id="target"></span>
<script type="text/javascript">
function executeMe(){
alert("9 seconds!");
}
var timeout = null;
var interval = null;
function timer(){
var now = new Date();
document.getElementById('time').innerHTML = now;
document.getElementById('target').innerHTML = new Date(now.getTime()+ 1000);
//console.log("timer()", now);
if(now.getSeconds() == 9)
setTimeout("executeMe();",1); // async
if(interval == null)
interval = setInterval("timer()",1000);
}
var now = new Date();
var target = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes(),now.getSeconds()+1,0);
//console.log("now", now);
//console.log("target", target);
//console.log("diff", target.getTime() - now.getTime());
document.getElementById('target').innerHTML = target;
timeout = setTimeout("timer()", target.getTime() - now.getTime() );
</script>
If you want to run the timer() every hour instead of every second, just adjust the target and the setInterval() and of course your conditions
Live Test: http://jsbin.com/ikulok/3/edit
<body>
Last run: <span id="time"></span><br>
Next execution: <span id="target"></span>
<script type="text/javascript">
function executeMe(){
alert("1:20am!");
}
var timeout = null;
var interval = null;
function timer(){
var now = new Date();
document.getElementById('time').innerHTML = now;
document.getElementById('target').innerHTML = new Date(now.getTime()+ 1*60*60*1000);
//console.log("timer()", now);
if(now.getHour() == 1)
setTimeout("executeMe();", 20*60*1000); // !!!! this will execute at 1:20am
if(interval == null)
interval = setInterval("timer()",1*60*60*1000); // !!!! repeat every hour
}
var now = new Date();
// !!!! targeting next exact hour
var target = new Date(now.getFullYear(),now.getMonth(),now.getDate(),now.getHours(),now.getMinutes()+1,0,0);
//console.log("now", now);
//console.log("target", target);
//console.log("diff", target.getTime() - now.getTime());
document.getElementById('target').innerHTML = target;
timeout = setTimeout("timer()", target.getTime() - now.getTime() );
</script>
</body>

To change a css style depending on time of day (javascript)

im trying to write a little .js file to change a css style from display:block to display:none depending on the time of day, 08.30 to 17.00 display block and 17.00 to 08.30 display none.
Here's what i have so far:
<script language="JavaScript">
day=new Date() //..get the date
x=day.getHours() //..get the hour
if(x>=8.30 && x<17) {
document.write('<style type="text/css">#live{display:block}"></style>')
} else
if(x>=17 && x<8.30) {
document.write('<style type="text/css">#live{display:none}"></style>')
};
</script>
Do think this is good js plus not sure if using 8.30 would work plus not sure if the last ";" is needed.
Any help on this would be great thanks.
Im now trying this code but does not work
<script type="text/javascript">
$(document).ready ( function (){
var dateObj = new Date();
var hour = dateObj.getHours() * 100 + dateObj.getMinutes();
if (hour >= 1600 && hour <= 1800) {
document.getElementById('live').style.display = "none";
}
});
</script>
Date().getHours() returns an integer. For your code to work you'd have to do something like this:
var dateObj = new Date();
var hour = dateObj.getHours() * 100 + dateObj.getMinutes();
if (hour >= 830 && hour <= 1700) {
document.getElementById('your_el').style.display = "none";
}
Note that you should only use this code when the DOM is ready for manipulation.
Although, is this really what you want? JavaScript's Date gets its date and time information from the users' clock. You would probably be better off handling this on the server.
getHours() returns a whole number (0 to 23). For 8:30, you will
need to check getHours() and getMinutes() accordingly.
The last semicolon does not need to be there.
getHours() only gets you the hours number, you need to get the minutes as well
try with
x=day.getHours()+ (day.getMinutes()/100);
about the ; it is not neccessary after an if, but it's good practice to put it at the end of each code line (that would be every other line)

Detecting changes to system time in JavaScript

How can I write a script to detect when a user changes their system time in JS?
There is no (portable) way to track a variable in JavaScript. Also, date information does not lie in the DOM, so you don't get the possibility of a DOM event being triggered.
The best you can do is to use setInterval to check periodically (every second?). Example:
function timeChanged(delta) {
// Whatever
}
setInterval(function timeChecker() {
var oldTime = timeChecker.oldTime || new Date(),
newTime = new Date(),
timeDiff = newTime - oldTime;
timeChecker.oldTime = newTime;
if (Math.abs(timeDiff) >= 5000) { // Five second leniency
timeChanged(timeDiff);
}
}, 500);
Check in an interval function that the time has not changed too much:
function getTime() {
var d = new Date();
return d.getTime();
}
function checkTime() {
if (Math.abs(getTime() - oldtime) > 2000) { // Changed by more than 2 seconds?
alert("You changed the time!");
}
oldtime = getTime();
}
var oldtime = getTime();
setInterval(checkTime, 1000); // Check every second that the time is not off
Tested on Windows with Opera & FF and works flawlessly.
Don't think there is a solution to what you are asking for but you can get the users timezone offset.
new Date().getTimezoneOffset() * -1
This returns the offset in minutes from GMT. Bare in mind though this does not take DST into consideration.
var last_time = new Date().getTime();
setInterval(function() {
var time = new Date().getTime();
var offset = time - last_time;
if(offset < 0 || offset > 1500) {
// Time has been changed
}
last_time = time;
}, 1000);
In theory, this should work. It will check every second to make sure the time hasn't been changed. Note that I use 1100 milliseconds as most JS interpreters don't fire off events at exactly the time specified.
Hope this helps!
use performance.now() to get duration, which will be independent of system clock
see https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
var t0 = performance.now();
doSomething();
var t1 = performance.now();
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.");
And then you can compare performance.now() elapsed with Date.now() elapsed to see whether they are diff too much.
Do you mean if they are changing their own system time to something that is wrong? You can ask the user for their time zone and get the correct time from the server, and then compare it to the user's system time.
You could check every 30 seconds, etc. If the new Time is off by more than 30 seconds +/- some threshold, you could do a more exhaustive comparison to determine how much it has been changed.

Categories

Resources