Changing the value of an object based on the time of day? - javascript

I'm creating a project that is a player attendance log. Every player is an object I created using class syntax and in theory the values of the object should change based on the time of day. This doesn't work because the values are either true or false regardless of what time of day it is. What is going wrong and how can I fix it? here's a link to my project https://github.com/bloodwolf616/project9
Problem code:
const today = new Date();
const hour = today.getHours();
const second = today.getSeconds();
for (let i = 0; i < attendance.length; i++){
if (hour > 10 && hour < 20) {
if(player1 && player2 && player3 && player4) {attendance[i]._online = true;}
} else {
attendance[i]._online = false;
}
if (second > 20 || second < 40) {
if(error) {
attendance[i]._online = true;}
} else {
attendance[i]._online = false;
}

Related

Increase a number based on Date or Interval javascript (and keep it after refresh page)

I'm struggling for while trying to figure out how to increase a number based on a Date or based on a time (Using setInterval).
I don't know which option is easier. I made it by using setInterval:
HTML
<p class="counter"></p>
JS
let tickets = 35000;
const counter = document.querySelector('.counter');
let interval = setInterval(function(){
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
}else{
var text = `¡${tickets} tickets Sold!`;
contador.innerHTML = text;
console.log(text)
}
const random = Math.floor(Math.random()*(200-100+1)+100);
tickets += random;
}, 10000);
The thing is every time the page is refreshed the counter starts from 35000 again. I am trying to figure out how to storage the var tickets. I guess this would be made by using localStorage, but since I am a beginner in JS, I am not able to do it.
Other option would be by checking the date, and based on that, show a number:
function date() {
var d = new Date();
var month = d.getMonth();
var day = d.getDate();
const counter = document.querySelector('.contador');
const random = Math.floor(Math.random()*(200-100+1)+100);
for (let i = 350000; i <= 60000 ; i++) {
if (month == 0 & day == 28) {
var sum = i + random;
document.getElementById("contador").innerHTML = suma;
}else if (mes == 0 & dia == 30) {
...
} else if (...){
...
}
}
document.getElementById("dia").innerHTML = dia;
document.getElementById("mes").innerHTML = mes;
}
fecha();
Could someone help me out to reach the result?
I would really appreciate it
The Storage object accessible via the localStorage property offers two methods to save or retrieve data: setItem and getItem().
Usage is quite simple. If you want to save the numbers of tickets into a myTickets key on localStorage you have to do it like this:
localStorage.setItem("myTickets", tickets);
To retrieve that data later on:
localStorage.getItem("myTickets");
You just have to make sure to update the myTickets key on localStorage as you increase the number of tickets inside the setinterval callback function.
let tickets = 35000;
if (localStorage.getItem("myTickets") == null) {
localStorage.setItem("myTickets", tickets);
} else {
tickets = localStorage.getItem("myTickets");
}
const counter = document.querySelector('.counter');
let interval = setInterval(function() {
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
} else {
var text = `¡${tickets} tickets Sold!`;
console.log(text)
}
const random = Math.floor(Math.random() * (200 - 100 + 1) + 100);
tickets += random;
localStorage.setItem("myTickets", tickets);
}, 10000);

JavaScript sorting on date (but not the "usual" way)

I'm trying to sort a JS array, but in a different fashion. Here's my scenario:
Say we have the following dates in the array (these will be each item's expiryDate)
1. 2015/09/23
2. 2015/10/10
3. 2015/07/05
4. 2015/07/24
And the current date is 2015/07/04
And we select 2015/09 (which is vm.sortModel in the example) as the sorting date
The display order must be as follows -
3.
1.
4.
2.
Here's what I have so far, but it's obviously not working...
for (var i = 0; i < vm.tableData.length; i++) {
var entity = vm.tableData[i];
entity.items.sort(function(a, b) {
if (a.expiresThisWeek() < b.expiresThisWeek()) {
return 1;
}
//Now check for stuff in months AFTER the selected year/month combo
if (vm.sortModel) {
var tmp = vm.sortModel.split('/');
var currentDateSelection = new Date(tmp[0], tmp[1]);
if (a.getExpiryDateObject() >= currentDateSelection) {
return 1;
} else {
return -1;
}
}
if (a.getExpiryDateObject() < b.getExpiryDateObject()) {
return -1;
} else if (a.getExpiryDateObject() > b.getExpiryDateObject()) {
return 1;
}
return 0;
});
}
Basically, if an item expires in this week, it must be at the top of the table, then we should list all the items in the "selected month", then all the months AFTER that month, and then only the months before that.
Very strange, I know, but business gets what business wants.
Thanks for any help!
EDIT
Here's the expiresThisWeek method
model.expiresThisWeek = function() {
var todayDate = new Date();
//We want to check if the item expires within 7 days from today
var endDate = new Date(todayDate.getFullYear(), todayDate.getMonth(), todayDate.getDate() + 7);
var date = model.getExpiryDateObject();
return todayDate < date && date < endDate;
}

Using timer behind multiple alerts and prompts

I have a game that I am making using only pure javascript. Instead of a GUI, It is more like the old command line games and uses a prompt for input.
One of the main components of it is the Clock, which is expressed in hours, and can be checked with the commmand "time" and tells them the value of the variable "time". Here is the code:
var timestrt = 1;
var timer = setInterval(function(){timestrt++;return timestrt;}, 86000); var time = timestrt;
After testing it, I realized that the clock was not changing. So I set it to 10 seconds instead of 86 to be sure that I was waiting long enough, and it still did not want to work
I know that it is probably caused by the prompt and constant alerts, but I am not sure even where to start for a workaround.
Any ideas?
Edit: is it possible to either
1. retrieve the timer from an external page
2. comparing it to an actual clock in real time or 3. Using a animated gif clock in the background and calculating the location of certain pixels as time?
Don't use the native prompts and dialogs, since they stop the script execution time. Instead use simulated ones, for example jQuery IU has prompts and dialog boxes that do not stop execution. Here is an example of that:
$(function() {
$( "#dialog" ).dialog();
var timestrt = 1;
var timer = setInterval(function(){
timestrt++;
var time = timestrt;
$("#time").text(time);
}, 1000);
});
Here is my workaround:
This code is called before the prompt is started:
function initTime() {
var now = new Date();
stS = now.getSeconds();
stM = now.getMinutes();
stH = now.getHours();
}
This is called after the prompt is done:
function computeTime() {
var now = new Date();
var reS = now.getSeconds();
var reM = now.getMinutes();
var reH = now.getHours();
var elapS = reS - stS;
var elapM = reM - stM;
var elapH = reH - stH;
if (elapM < 0) {
reM = reM + 60;
elapM = reM - stM;
}
if (elapS < 0) {
reS = reS + 60;
elapS = reS - stS;
}
Then I convert it to seconds to make it easier to check against:
var finalH = elapH * 3600;
var finalM = elapM * 60;
var finalS = finalM + elapS + finalH;
And check/change the time variable based on how many sets of 86 seconds has passed:
if (finalS > 86 && finalS < 172) {
time = 1;
}
if (finalS > 172 && finalS < 258) {
time = 2;
}
if (finalS > 258 && finalS < 344) {
time = 3;
}
if (finalS > 344 && finalS < 430) {
time = 4;
}
if (finalS > 430 && finalS < 516) {
time = 5;
}
if (finalS > 516) {
time = 6;
alert('5 A.M.');
alert('A clock is chiming...');
alert('6 A.M.');
playing = false;
alert('Thanks for playing! Goodbye!');
}
And that is my alternative to using a setinterval/timer behind multiple prompts and alerts. The last part probably wasn't needed, but since it answered my original question I included it.

Optimizing a functions performance using a loops wall-time

I use the following function below to update and call a drawAccel();function that builds out an animated strip chart.
function messagecb(header, message) {
if(header.type == 6) {
// processEchoReply(message);
} else if(header.type == 4) {
// accel
var accels = message.b64UnpackAccelMsg();
for(var index = 0; index < accels.length; ++index) {
var accel = accels[index];
var totalClock = accelEpochAdjust(accel.clock);
addAccelDatum(totalClock, accel.x, accel.y, accel.z);
}
if ( typeof messagecb.counter == 'undefined' ) {
messagecb.counter = 0;
}
++messagecb.counter;
if (messagecb.counter % 10 === 0) {
drawAccel();
}
} else if(header.type == 3) {
// info
var info2 = message.b64UnpackInfo2Msg();
displayCurrentPosition(info2.fixtime, info2.lat, info2.lon, info2.alt);
displayMobileStatus(info2.rssi, info2.bandClass, info2.batt);
} else if(header.type == 11) {
btReceive(header, message);
}
}
I come across some intermittent performance issues in IE8 though. So I would like to
collect the elapsed wall time running inside the update for loop, and not call the drawAccel() renderer unless I'm using less than 50% of the wall time.
Pseudo code example:
if ((lastEnteredTime - lastExitedTime)/(currentTime - lastEnteredTime) < .5){
drawAccel();
} else {
//do nothing
}
My problem is I'm not sure how I can go about getting the last entered time and the last exited time of the loop so that I can run this condition. Any ideas? Thanks!
It's not clear to me exactly what you're trying to do, but something like this should get you close. +new Date() will give you the number of milliseconds since 1/1/1970, so making that same call at various places should be able to get you what you want
var start = +new Date();
for(var index = 0; index < accels.length; ++index) {
var accel = accels[index];
var totalClock = accelEpochAdjust(accel.clock);
var current = +new Date();
var timeElapsedInMs = current - start;
//not sure the exact test you want to run here
addAccelDatum(totalClock, accel.x, accel.y, accel.z);
}
Edit based on your comment. So if you always want to have a lastEntered and lastExited values, something like this might be what you want
var lastEntered, lastExisted = +new Date();
for(var index = 0; index < accels.length; ++index) {
lastEntered = +new Date();
var accel = accels[index];
var totalClock = accelEpochAdjust(accel.clock);
var timeElapsedInMs = current - start;
//not sure the exact test you want to run here
addAccelDatum(totalClock, accel.x, accel.y, accel.z);
lastExisted = +new Date();
}
And from there you can do whatever comparisons you need.

10ms Interval with firefox

So I made a simple timer in a format like this: MM:SS.MS
You can view it here [removed]
It works fine in chrome, IE, etc. but in Firefox the seconds are like twice as long..
I took a look at some other stopwatches, but I don't quit understand them.
Whats the best way to do it ? Right now I have a 10ms interval which generates the timer.
The function looks like that, I hope it's understandable:
var state = false;
var msTimer = null;
var min = document.getElementById("min");
var sec = document.getElementById("sec");
var ms = document.getElementById("ms");
var minCount = 0;
var secCount = 0;
var msCount = 0;
document.onkeydown = function timer(e) {
if (!e) { e = window.event; }
if (e.keyCode == "32") {
if (state == false) {
state = true;
min.innerHTML = "00";
sec.innerHTML = "00";
ms.innerHTML = "00";
msTimer = window.setInterval(function() {
if (msCount == 99) {
msCount = 0;
secCount++;
// Minutes
if (secCount == 60) {
secCount = 0;
minCount++;
if (minCount <= 9)
{ min.innerHTML = "0" + minCount; }
else
{ min.innerHTML = minCount; }
}
// Seconds
if (secCount <= 9)
{ sec.innerHTML = "0" + secCount; }
else
{ sec.innerHTML = secCount; }
} else { msCount++; }
// Miliseconds
if (msCount <= 9)
{ ms.innerHTML = "0" + msCount; }
else
{ ms.innerHTML = msCount; }
// 1 Hour
if (minCount == 60) {
clearInterval(msTimer);
min.innerHTML = "N0";
sec.innerHTML = "00";
ms.innerHTML = "0B";
state = false;
minCount = 0;
secCount = 0;
msCount = 0;
}
}, 10);
} else if (state == true) {
state = false;
clearInterval(msTimer);
minCount = 0;
secCount = 0;
msCount = 0;
}
}
Thanks for any advices :)
Edit:
And btw, it's much smoother in firefox, if I remove all styles from the timer.
But that can't be the solution..
You shouldn't be relying on the interval of the timer being exactly 10ms. It would be better if you viewed each timer tick as a request to refresh the on-screen timer, but take the measurements from the system clock or something like that.
Then however slow or busy the machine (and JS implementation) is, you'll always see an accurate timer1 - just one which updates less often.
1 This will only be as accurate as the system clock, of course. If Javascript has access to a high-performance timer like .NET's Stopwatch class or Java's System.nanoTime() method, that would be better to use.
Timing in Javascript is not guaranteed. A 10ms interval will only ever be approximately 10ms, most likely it will be delayed a tiny bit each time. The correct way to do a timer in Javascript is to save a starting timestamp upon starting the timer, then each 10ms or so calculate the difference between the starting timestamp and the current time and update an element on the page with the formatted value.

Categories