I have a timestamp and I need to run my code 30 seconds before timestamp is reached.
Logic
Get current time
Get database timestamp
Run code 30 seconds before database timestamp
sample code
const now = moment(); // current time
const then = moment.unix(chainIds[i].timestamp); // returns: 2023-02-15T18:11:00+07:00
// run something (console log perhaps)
so based on my database timestamp my code has to be run at 18:10:30
actual code
Note: problem with this code is that its running even days after timestamp is passed.
const now = moment();
const then = moment.unix(chainIds[i].timestamp);
const delta = now.diff(then, 'seconds'); // get the seconds difference
var itstime = false;
if(moment.unix(delta).format("ss") <= 30){
itstime = false;
} else {
itstime = true;
}
I know I'm close to the solution but there is a bug that I can't figure it, any idea?
You can add a minimum value condition to make sure it won't run too far after the target. Here I'm giving it a 60 second buffer so that it will still run if the code isn't triggered exactly at 30 seconds, but you can adjust that to your needs.
var itstime = false;
var seconds = moment.unix(delta).format("ss");
if(seconds <= 30 && seconds >= -30){
itstime = false;
} else {
itstime = true;
}
You can make it a lot more simple
const now = moment();
const then = moment.unix(chainIds[i].timestamp);
const delta = now.diff(then, 'seconds');
var itstime = false;
if(delta < 30){
itstime = true;
}
I am not super sure but from what I understood, your difference is getting a second time, now.diff gets the result, see
https://www.geeksforgeeks.org/moment-js-moment-diff-function/
so I don´t think you need
moment.unix(delta).format("ss") <= 30
have you tried something like
const now = moment();
const then = moment().add('minutes', 1);
const delta = now.diff(then, 'seconds'); // get the seconds difference
var itstime = false;
if (delta <= 30) {
itstime = false;
} else {
itstime = true;
}
Related
Let's suppose I have a array list with all these following data.
let events = {
["-1 19:00"],
["-1 20:00"],
["-1 17:00", "-1 23:00"],
["1 18:00"],
["2 18:00"],
["3 18:00"],
["4 18:00"],
["5 18:00"],
["6 18:00"],
["7 18:00"],
};
So, Here -1 represents every single day, Like every "sunday, monday" and so on. -1 = everyday, 1 = Monday, 2 = Tuesday and so on.
So, I want to calculate The time left from the current time to the nearest day with hours and mins inside the array. I'm really lacking idea on how I'm supposed to do it.
getTimeLeftTillDay(dayname, time) :any {
let d = new Date();
let coming = parseInt(dayname);
if(coming === -1) {
coming = d.getDay();
}
const day = d.getDay();
const targetDay = coming; // Someday
let dayOffset = targetDay - day;
if (dayOffset < 0) dayOffset += 7;
d = new Date(d.getTime() + (dayOffset * 24 * 3600 * 1000));
let timea = parseInt(time[0]);
let timeb = parseInt(time[1]);
d.setHours(timea);
d.setMinutes(timeb);
return d;
}
I tried to use the above code but it doesn't work as I expected. I'll really like help!
If relying on a 3rd-party library is ok for you, I'd use one of the many date-libs to perform the calculations. Here's how you could do it using date-fns:
import {addDays, formatDuration, intervalToDuration, setHours, setMinutes} from "date-fns";
const getTimeLeftTillDay = (dayName, time) => {
let daysToAdd = 0;
if (dayName !== '-1') {
daysToAdd = Number.parseInt(dayName);
}
const startDate = new Date();
let endDate = addDays(startDate, daysToAdd);
const [minutes, seconds] = time.split(":");
const hoursToSet = Number.parseInt(minutes);
endDate = setHours(endDate, hoursToSet)
const minutesToSet = Number.parseInt(seconds);
endDate = setMinutes(endDate, minutesToSet)
return customFormatDuration(startDate, endDate);
}
export const customFormatDuration = (start, end) => {
const durations = intervalToDuration({start, end})
return formatDuration(durations);
}
console.log(getTimeLeftTillDay("-1", "19:00"));
console.log(getTimeLeftTillDay("1", "02:00"));
console.log(getTimeLeftTillDay("7", "02:00"));
This prints the following on my machine (executed at 2:25 pm, CET):
4 hours 35 minutes
11 hours 35 minutes
6 days 21 hours 35 minutes
If you want to consider cases where the calculated time is before the current time and you want to treat them as "next-day" and handle days in the past in general, you can do:
const getTimeLeftTillDay = (dayName, time) => {
const startDate = new Date();
let dayToSet = getDay(startDate);
if (dayName !== '-1') {
dayToSet = Number.parseInt(dayName) - 1;
}
let endDate = new Date();
const [minutes, seconds] = time.split(":");
const hoursToSet = Number.parseInt(minutes);
endDate = setHours(endDate, hoursToSet)
const minutesToSet = Number.parseInt(seconds);
endDate = setMinutes(endDate, minutesToSet)
endDate = setDay(endDate, dayToSet);
if (isBefore(endDate, startDate)) {
endDate = addDays(endDate, 1);
}
return customFormatDuration(startDate, endDate);
}
i was wondering how to make a Command Cool-down for a single command and not all the other commands? it would be much appreciated if someone helps me out on this, Thank you in advanced.
You are going to have to create a Collection() that will contain the users that have executed a command and then have a client.setTimeout() function to remove the users after a set time from the Collection() so that they can use commands again.
Here is an example from this guide:
const cooldowns = new Discord.Collection();
if (!cooldowns.has(command.name)) {
cooldowns.set(command.name, new Discord.Collection());
}
const now = Date.now();
const timestamps = cooldowns.get(command.name);
const cooldownAmount = (command.cooldown || 3) * 1000;
if (timestamps.has(message.author.id)) {
// ...
}
if (timestamps.has(message.author.id)) {
const expirationTime = timestamps.get(message.author.id) + cooldownAmount;
if (now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
return message.reply(`please wait ${timeLeft.toFixed(1)} more second(s) before reusing the \`${command.name}\` command.`);
}
}
I have started a game and I want a stopwatch (countup timer) in it I have found a code to activate it. But how to stop it?
Source: https://docs.idew.org/video-game/project-references/phaser-coding/timers#create-count-up-timer
Code related to the stopwatch:
//global vars
var timeText; var min, sec;
function create timeText = game.add.text(600, 20, "", { fontSize: '20px', fill: '#FFF' }); timeText.fixedToCamera = true;
function displayTimeElapsed(){
if (knight.x >= 96){
var time = Math.floor(game.time.totalElapsedSeconds() );
min = Math.floor(time / 60);
sec = time % 60;
if (min < 10) {
min = "0" + min;
}
if (sec < 10) {
sec = "0" + sec;
}
timeText.text = "Time: " + min + ":" + sec;
}
}
//update displayTimeElapsed();
you could add a boolean pause that if true it will set the time to what the remaining time is and when false keep doing what is doing.
it would be easier to explain it if you show your code. I will update my answer accordingly.
Lets create it from scratch,
first of all in your create() function, lets add a text to display the timer on the screen:
// CREATE()
this.timerText = this.add.text(x, y, "").setColor("#000000");
Second lets create a function, bellow the update(), to count down :
showTimer(){
// Assuming you want 60 seconds, if not just chenge the 60's for whatever time you want
let maxTime = 60;
let time = Math.floor(this.time.totalElapsedSeconds() );
let sec = time % 60;
timeText.setText(sec); // Adding the timer to our text
}
Third, create a variable in the create() to track when the timer ends:
// CREATE()
this.timerOver = false;
// And lets start the timer
this.timer = this.time.delayedCall(60000);
Now lets modify our showTimer() function:
showTimer(){
let maxTime = 60;
let time = Math.floor(this.time.totalElapsedSeconds() );
let timeLeft = maxTime - time; // Check how much time is left
// When the countdown is over
if(timeLeft <= 0){
timeLeft = 0;
this.timerOver = true; // Setting our variable to true
}
let sec = time % 60;
timeText.setText(sec);
}
and last, in our update() function lets check if our variable this.timerOver is true
if (this.timerOver === false){
this.showTimer(); // Calling our function every frame
}
else {
// Whatever you want it to do when timer comes to 0
}
When I move the function 'send()' within this function, the code stops working.
I didn't get any errors, the program just became unresponsive. I have no idea why and it took me an half hour to figure out how to solve the problem. I'd like to know what this caused and how to prevent it in the future.
Thanks in advance.
Working code:
function warn(channelID, userID, reason){
if(!userExists(channelID, userID)) return;
var warnings = players[userID].warnings;
var today = new Date().getTime();
var active = 0;
for (key in warnings){
date = warnings[key].date;
if(today - date < 60*1000){
active++;
}
}
if (active >= 3){
kick(channelID, userID, "You have been automatically kicked after 3 (active) warnings.");
log("Bot", userID, "kick", "3 warnings");
}
send(channelID, reason); //this function
}
Code stopped working after moving the 'send()' function:
function warn(channelID, userID, reason){
if(!userExists(channelID, userID)) return;
var warnings = players[userID].warnings;
var today = new Date().getTime();
var active = 0;
for (key in warnings){
date = warnings[key].date;
if(today - date < 60*1000){
active++;
}
}
send(channelID, reason); //this function
if (active >= 3){
kick(channelID, userID, "You have been automatically kicked after 3 (active) warnings.");
log("Bot", userID, "kick", "3 warnings");
}
}
The code started working again after I added 'return;' add the end of the function.
function warn(channelID, userID, reason){
if(!userExists(channelID, userID)) return;
var warnings = players[userID].warnings;
var today = new Date().getTime();
var active = 0;
for (key in warnings){
date = warnings[key].date;
if(today - date < 60*1000){
active++;
}
}
send(channelID, reason);
if (active >= 3){
kick(channelID, userID, "You have been automatically kicked after 3 (active) warnings.");
log("Bot", userID, "kick", "3 warnings");
}
return;
}
I have been developing in PHP for many years and now I´m trying to learn NodeJS, and I´m having problems with asynchronous functions...
I have this function in NodeJS (source is an array of users):
//userformat.js
var age = module.exports.age = function(date){
var diff = new Date - new Date(date);
var diffdays = diff / 1000 / (60 * 60 * 24);
var age = Math.floor(diffdays / 365.25);
return age;
}
...etc.
//index.js
function format(source, me, callback){
var len = source.length
for (var i = 0; i < len; i++){
source[i]['_age'] = userFormat.age(source[i]['birthday']);
source[i]['_rating'] = userFormat.rating(source[i]['votes']);
source[i]['_is_followed'] = userFormat.followed(source[i]['fllws'], me);
}
callback(null, source);
}
I know that function is wrong in Node, because is possible that the function calls the callback before the functions in the for() had finished, and the values in the array could be undefined, for this reason I changed the function using callbacks:
//userformat.js
var age = module.exports.age = function(date, callback){
var diff = new Date - new Date(date);
var diffdays = diff / 1000 / (60 * 60 * 24);
var age = Math.floor(diffdays / 365.25);
callback(age);
}
...etc.
//index.js
function format(source, me, callback){
var len = source.length
for (var i = 0; i < len; i++){
userFormat.age(source[i]['birthday'], function(resul){
source[i]['_age'] = resul;
userFormat.rating(source[i]['votes'], function(resul){
source[i]['_rating'] = resul;
userFormat.followed(source[i]['fllws'], me, function(resul){
source[i]['_is_followed'] = resul;
//Callback
if (i == len-1){
callback(null, source);
}
})
})
})
}
}
That is correct? I have another way to do it more efficient or elegant?
Thank you so much!
I think you misunderstood the concept of asynchronous in nodeJS. Your code isn't asynchronous and your callback will always be called after the loop.
Check this question : how do i create a non-blocking asynchronous function in node.js?