I'm trying to do a program which executes after 15 minutes of being in the page. My problem is how to get the exact number to add on the timestamp which is stored in a cookie.
I need a function to convert seconds into timestamps or anything that can make the action execute after 15 minutes. I don't really know how much time is 1792939 which I place in the code below.
setInterval("timer()",1000);
$.cookie("tymz", time);
function timer(){
var d = new Date();
var time = d.getTime();
var x = Number($.cookie("tymz")) + 1792939;
//alert('Cookie time: ' + x + '\nTime: ' + time);
if(time > x){
alert('times up');
}else{
//alert('not yet\n' + 'times up: ' + x + '\ntime: ' + time);
}
}
How about using setTimeout(..)?
<script type="text/javascript">
function myFunc()
{
alert("I will show up 15 minutes after this pages loads!");
}
setTimeout("myFunc()",60*15*1000);
</script>
Check this: http://www.w3schools.com/js/js_timing.asp
unix timestamp are second from epoch (1/1/1970) so if you want to execute some code after 15 minutes just record the time when the page is loaded then every second calculate how many seconds are passed from page load. When the difference between current time and page load time is greater than 15*60*1000 you can execute your code.
var pageLoad = new Date().getTime();
function tick(){
var now = new Date().getTime();
if((now - pageLoad) > 15*60*1000) executeYourCode();
}
setInterval("tick()",1000);
Remeber that javascript return time in millisecond
Hope this helps
If the number is seconds since 1/1/1970 00:00:00, then you can convert '1792939' to a javascript date by multiplying by 1,000 and passing to Date:
var d = new Date(1792939 * 1000) // Thu Jan 22 1970 04:02:19
Currently it is about 1311428869 seconds since 1/1/1970. So if you have a value for seconds, then you can use setInterval to run a function 15 minutes after that:
var seconds = ?? // set somehow
var start = new Date(seconds * 1000);
var now = new Date();
var limit = 15 * 60 * 1000;
var lag = now - start + limit;
// Only set timeout if start was less than 15 minutes ago
if ( lag > 0 ) {
setTimeout( someFn, lag);
}
Provided the current time is less than 15 minutes from the start time, the function will run at approximately 15 minutes after the start time. If the system is busy when the time expires, the function should be run as soon as possible afterward (usually within a few ms, but maybe more).
works without server or cookie (and all browser after IE7)
Looks like you use jQuery, so you might as well use jQuery.now() insted
var firstVisit = localStorage['firstVisit'] = localStorage['firstVisit'] || $.now();
function myFunc(){
alert("I will show up 15 minutes after this pages loads!");
}
setTimeout(myFunc, parseInt(firstVisit) - $.now() + 1000 * 60 * 15);
Related
I am trying to update information from a weather service on my page. The info should be updated every hour on the hour. How exactly do I go about calling a function on the hour every hour?
I kind of had an idea but I'm not sure of how to actually refine it so it works...
What I had in mind was something like creating an if statement, such as: (pseudo code)
//get the mins of the current time
var mins = datetime.mins();
if(mins == "00"){
function();
}
You want to check out setInterval: https://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval
It's a little hard to tell what you're trying to call with your code, but it would be something in the form of:
function callEveryHour() {
setInterval(yourFunction, 1000 * 60 * 60);
}
If you want it every hour, try something like:
var nextDate = new Date();
if (nextDate.getMinutes() === 0) { // You can check for seconds here too
callEveryHour()
} else {
nextDate.setHours(nextDate.getHours() + 1);
nextDate.setMinutes(0);
nextDate.setSeconds(0);// I wouldn't do milliseconds too ;)
var difference = nextDate - new Date();
setTimeout(callEveryHour, difference);
}
Now, this implementation checks the time once, sets the delay (or calls the function immediately), and then relies on setInterval to keep track after that. An alternative approach may be to poll the time every x many seconds/minutes, and fire it .getMinutes() == 0 instead (similar to the first part of the if-statement), which may sacrifice (marginal) performance for (marginal) accuracy. Depending on your exact needs, I would play around with both solutions.
Here is what should work (JSFiddle):
function tick() {
//get the mins of the current time
var mins = new Date().getMinutes();
if (mins == "00") {
alert('Do stuff');
}
console.log('Tick ' + mins);
}
setInterval(tick, 1000);
What you probably want is something like that:
var now = new Date();
var delay = 60 * 60 * 1000; // 1 hour in msec
var start = delay - (now.getMinutes() * 60 + now.getSeconds()) * 1000 + now.getMilliseconds();
setTimeout(function doSomething() {
// do the operation
// ... your code here...
// schedule the next tick
setTimeout(doSomething, delay);
}, start);
So basically the first time the user get the access, you need to know what is the delay in millisecond to the next "hour". So, if the user access to the page at 8:54 (with 56 seconds and 123 milliseconds), you have to schedule the first execution after around 3 minutes: after the first one is done, you can call it every "hour" (60 * 60 * 1000).
Repeat at specific minute past the hour
This counter is a little bit more versatile; it allows to perform a task repeatedly always at the same minute past the hour (e.g. 37 minutes past the hour), and this with up to millisecond precision.
The precision of this timer is derived from its recursion.
At every recursion, the millisecond time to the next minute gets recalculated. This prevents time lag over long periods.
The % sign refers to the modulo operator.
function minuteCount(minutesAfterHour) {
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
const milliseconds = now.getMilliseconds();
waitUntilNextMinute = setTimeout(minuteCount, 60000 - seconds * 1000 - milliseconds);
if(minutes % 60 === minutesAfterHour) {
doSomethingHourly();
}
}
minuteCount(37);
Finally, timers are best kept away from the main thread. They are best run from within a web worker, as explained here.
This works perfectly with unfocused tabs in desktop browsers.
However, dedicated web workers on Chrome for Android are put to sleep about 5 minutes after moving the main client to the background.
EDIT: Oops, I didn't see the " o' clock" things, so I edit my answer :
var last_execution = new Date().getTime();
function doSomething(force){
var current_time = new Date().getTime();
if (force || (current_time.getMinutes() == 0)
{
last_execution = current_time;
// something
// ...
}
setTimeout(doSomething(false), 1000);
}
// force the first time
doSomething(true);
// ... call your func now
let intervalId;
let timeoutId = setTimeout(() => {
// ... call your func on end of current hour
intervalId = setInterval(() => {
// ... call your func on end of each next hours
}, 3600000);
}, ((60 − moment().minutes()) × 60 × 1000) - (moment().second() * 1000));
Here is my pair of setIntervalWithDelay and clearIntervalWithDelay that one can use like this:
let descriptor = setIntervalWithDelay(callback, 60 * 60 * 1000, nextHourDelay)
And when you are done with it:
clearIntervalWithDelay(descriptor)
Here is my implementation of the functions:
const setIntervalWithDelay = (callback, interval, delay = 0) => {
let descriptor = {}
descriptor.timeoutId = setTimeout(() => {
if(!descriptor.timeoutId){
return
}
descriptor.timeoutId = null
callback()
descriptor.intervalId = setInterval(callback, interval)
}, delay)
return descriptor
}
export const clearIntervalWithDelay = (descriptor) => {
if(!isObject(descriptor) || (!descriptor.timeoutId && !descriptor.intervalId)){
console.warn("clearIntervalWithDelay: Incorrect descriptor. Please pass an object returned by setIntervalWithDelay. Skipping this call.")
return
}
if(descriptor.timeoutId){
clearTimeout(descriptor.timeoutId)
descriptor.timeoutId = null
console.log("clearIntervalWithDelay: stopped during delay.")
}
if(descriptor.intervalId){
clearInterval(descriptor.intervalId)
descriptor.intervalId = null
console.log("clearIntervalWithDelay: stopped during interval repeat.")
}
}
One example of using dayjs to get the delay for the next hour:
let nextHour = dayjs().second(0).millisecond(0).add(1, "hour")
let nextHourDelay = nextHour.diff(dayjs())
I'm trying to edit following code to get the output I want.
function zoo_countdown_end_day() {
if ($('.zoo-get-order-notice .end-of-day')[0]) {
var offset = $('.end-of-day').data('timezone');
var day = new Date();
var utc = day.getTime() + (day.getTimezoneOffset() * 60000);
let d = new Date(utc + (3600000*offset)),
duration = 60 * (60 - d.getMinutes());
let timer = duration, minutes;
let hours = (23 - d.getHours());//kumudu edited this
hours = hours < 10 ? '0' + hours : hours;
let label_h = $('.zoo-get-order-notice .end-of-day').data('hours');
let label_m = $('.zoo-get-order-notice .end-of-day').data('minutes');
setInterval(function () {
minutes = parseInt(timer / 60, 10);
minutes = minutes < 10 ? "1" + minutes : minutes;
$('.zoo-get-order-notice .end-of-day').text(hours + ' ' + label_h + ' ' + minutes + ' ' + label_m);
if (--timer < 0) {
timer = duration;
}
}, 1000);
}
}
zoo_countdown_end_day();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="zoo-get-order-notice">
<span class="end-of-day"
data-timezone="+3"
data-hours="1"
data-minutes="3"></span>
</div>
This is the current output:
I just want to edit countdown time to countdown from next day 4.00 P.M (hours and minuets). Because I offer next day shipping.
Ok, the long and short of this answer is that it uses 2 functions to help..
countDown: this function takes in a functionwhileCountingDown, a numberforHowLong, then another functionwhenFinishedThen
whileCountingDown being triggered EACH second with the parameter being the amount of time left in seconds
forHowLong is the amount of seconds this countdown will last
whenFinishedThen is a function that activates AFTER the countdown is over.. it can be anything(like making a new countdown as well)
timeParse: this function takes in a numberseconds and then returns a string that looks like a more human version of time
eg: timeParse(108010), 108010 is 30 hours and 10 seconds, and it would return "1 day, 6 hours, 0 minutes"
The combination of these functions are able to have a countdown system working very well.. I ALSO DO NOT KNOW WHERE YOU GET YOUR FUTURE TIME FROM,
but if you get it in a timestamp format(like 1611860671302, a value that I copied from new Date().getTime() as I was typing this),
the line where you see 30*3600, replace that line with ((dateStamp-new Date().getTime())/1000).toFixed(0)
//honestly I don't even see where it's counting down from so i just made a countdown function that works in seconds and scheduled 30 hours from now(from when you run code).. just the format would probably need changing(since i don't know what format you want)
function zoo_countdown_end_day() {
var elem=$('.zoo-get-order-notice .end-of-day')[0]
//like I said, I didn't even see where you're taking the future time from but I'll just give a future time the equivalent of +30 hours
countDown(
(t)=>elem.innerText=timeParse(t), //every second, remaining time shows in specified element
30*3600, //seconds equivalent for 30 hours.. if you have a future dateStamp, before the countdown function, let dateStamp=this datestamp you would have, THEN change this line to.. ((dateStamp-new Date().getTime())/1000).toFixed(0)
()=>console.log("Timer Complete")
)
}
zoo_countdown_end_day();
//...............................................................
//time parsing function(takes in seconds and returns a string of a formatted date[this is what can change to change the look])
function timeParse(seconds){
var words=[
(num)=>{if(num==1){return("second")}return("seconds")},//this would return a word for seconds
(num)=>{if(num==1){return("minute")}return("minutes")},//this would return a word for minutes
(num)=>{if(num==1){return("hour")}return("hours")},//this would return a word for hours
(num)=>{if(num==1){return("day")}return("days")}//this would return a word for days
]
var timeArr=[seconds]
if(timeArr[0]>=60){//if seconds >= 1 minute
timeArr.unshift(Math.floor(timeArr[0]/60))
timeArr[1]=timeArr[1]%60
if(timeArr[0]>=60){//if minutes >= 1 hour
timeArr.unshift(Math.floor(timeArr[0]/60))
timeArr[1]=timeArr[1]%60
if(timeArr[0]>=24){//if hours >= 1 day
timeArr.unshift(Math.floor(timeArr[0]/24))
timeArr[1]=timeArr[1]%24
}
}
}
timeArr=timeArr.reverse()
.map((a,i)=>`${a} ${words[i](a)}`)
.reverse() //puts words to values and then reverses it back to correct order
timeArr.splice(timeArr.length-1,1) //takes out seconds part from being returned leaving days, minutes and hours
return(timeArr.join(', ')) //a mixture/combination of the forEach formatting(joining numbers with words), what is returned from words array and how they're joined contributes to the formatted look
}
//...............................................................
//countDown function(that works in seconds)
function countDown(whileCountingDown, forHowLong, whenFinishedThen){
//basic run down is, whileCountingDown is a function, forHowLong is a number, whenFinishedThen is a function
//in depth run down is:
/*
whileCountingDown(with parameter of how much time left in seconds) is activated every second until forHowLong seconds has passed, then whenFinishedThen is triggered
*/
var i=setInterval(()=>{forHowLong--
if(forHowLong<=0){//count finished, determine what happens next
clearInterval(i); whenFinishedThen()
}
else{whileCountingDown(forHowLong)}//do this for each second of countdown
},1000)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="zoo-get-order-notice">
<span class="end-of-day"
data-timezone="+3"
data-hours="1"
data-minutes="3"></span>
</div>
Need to display current time in JS with the given functions.
Internet searches showed JS using Date() and Time() for gathering the info, but the date and time are not showing up in the HTML when run it.
"use strict";
var $ = function(id) { return document.getElementById(id); };
var displayCurrentTime = function() {
var now = new Date(); //use the 'now' variable in all calculations, etc.
var Date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var hours = now.getHours()+ ":" + now.getMinutes() + ":"
+ now.getSeconds();
//Ok, problem now is getting HTML to call it up?
};
var padSingleDigit = function(num) {
if (num < 10) { return "0" + num; }
else { return num; }
};
window.onload = function() {
// set initial clock display and then set interval timer to display
// new time every second. Don't store timer object because it
// won't be needed - clock will just run.
};
Instructor's instructions:
"Note that to convert the computer’s time from a 24-hour clock to a 12-hour clock, first check to see if the hours value is greater than 12. If so, subtract 12 from the hours value and set the AM/PM value to “PM”. Also, be aware that the hours value for midnight is 0.
The starter project has four functions supplied: the $ function, the start of a displayCurrentTime() function, a padSingleDigit() function that adds a leading zero to single digits, and the start of an onload event handler.
In the displayCurrentTime() function, add code that uses the Date object to determine the current hour, minute, and second. Convert these values to a 12hour clock, determine the AM/PM value, and display these values in the appropriate span tags.
Then, in the onload event handler, code a timer that calls the displayCurrentTime() function at 1 second intervals. Also, make sure that the current time shows as soon as the page loads. (some comments have been included in the starter code to guide you on where to place things)."
In order to grap an html element you first need one. So i made a tag with an id of "clock". I then set an interval, running every 1000 milis (1 second) to give me the correctly formatted time.
clock = document.getElementById("clock");
let hours, minutes, seconds;
function checkDigits(num, hours) {
if (num < 10) {
return "0" + num
} else {
if (hours) {
return num - 12
}
return num
}
}
function updateTime() {
date = new Date();
hours = checkDigits(date.getHours(), true)
minutes = checkDigits(date.getMinutes())
seconds = checkDigits(date.getSeconds())
clock.innerHTML = hours + ":" + minutes + ":" + seconds;
}
window.onload = function() {
setInterval(function() {
updateTime()
}, 1000);
}
<h1 id="clock"></h1>
i am trying to create a program that will run for X amount of minutes.
minutes was always set to 1 in testing
var minutes = $('#minutes').val();
var runtime = minutes*60; // gets the seconds
var secondsEpoch = new Date() / 1000; // Epoch time
var End = secondsEpoch + runtime; // add the minutes to the current epoch
if (secondsEpoch < End) {
window.setInterval(RunClock, 1000/10);
} else {
clearInterval(RunClock);
}
function RunClock() {
console.log(new Date() / 1000);
//my code
}
The script runs for infinity and i'm confused on why ???
When alerting variable secondsEpoch and End i always end up with a time difference of 1 minute?
Alerted the start and finish times and got
Start 1395022190.621
Finish 1395022250.621
Total difference of 60 which = 1 minute
but the console log at this minute is
1395022456.657
which is obviously greater than
1395022250.621
and the scrip is still running and not stopping
You are not clearing your interval correctly. This way it will work:
var interval;
if (secondsEpoch < End) {
interval = setInterval(RunClock, 1000/10);
} else {
clearInterval(interval);
}
I'm writing a Greasemonkey script where I want to know when it was last run. To do this, I wanted to store the current time with GM_setValue and compare that time to the time when the script is run again.
However, it seems that the Date().getTime() results won't pass to GM_setValue. For instance if you run:
var newtime = new Date().getTime();
GM_setValue('lastrun', newtime);
alert(GM_getValue('lastrun'));
There's obviously errors since the alert box won't pop up. However if you replace the first line with:
var newtime = 1;
you then get 1 returned in the alert box like you would expect.
That pretty much just isolates the date format causing the issue here. Any ideas on how to deal with this, or better ways to save dates between times a script has run?
I had a similar issue. The number is too large to be stored as a firefox cookie value. My solution was to limit the precision to the second (divide by 1000, drop remainder) and subtract 43 years (1356998400 seconds) to bring the date measured from to Midnight Jan 1st 2013 so my code looks like this:
var time = Math.floor((new Date().getTime() / 1000) - 1356998400);
GM_setValue("runTime", time);
and the retrieval looked like:
var time = GM_getValue("runTime", 0);
if (time != 0) {
var cur = Math.floor((new Date().getTime() / 1000) - 1356998400);
var cur = cur - time;
var sec = cur % 60;
var min = Math.floor(cur / 60);
console.log("Script took " + min + ":" + sec);
}