Moment is getting the wrong date in Node JS mssql query - node.js

I am trying to pass moment dates as variables in a query. When I console log the dates are correct but when the query runs it gets the current date -1...
Here is the code:
const dateEnd = moment().format('YYYY-MM-DD 23:59:59');
const dateStart = moment().format('YYYY-MM-DD 00:00:00');
// console.log(dateEnd)<-- They come back correct
// console.log(dateStart)
// process.exit();
let pool = await sql.connect(dbconfig)
//Get records from table
let getRecords = await pool.request()
.input('dateStart', sql.Date, dateStart)
.input('incrm', sql.VarChar, 'yes')
.input('dateEnd', sql.Date, dateEnd)
.query('select * from database.dbo.table where someValue in (231312,7132133) and incrm=#incrm and processeddate between #dateStart and #dateEnd and email is not null')

The node-mssql library expects dates to be passed as Date objects.
Try this, if you want the current day in the same time zone as the machine you're running this code from:
const dateStart = moment().startOf('day').toDate();
const dateEnd = moment().endOf('day').toDate();
Or, if you want the current UTC day, then:
const dateStart = moment.utc().startOf('day').toDate();
const dateEnd = moment.utc().endOf('day').toDate();
Or, if you want the current day in a particular time zone (say US Central Time), then use the moment-timezone add-on library:
const dateStart = moment.tz('America/Chicago').startOf('day').toDate();
const dateEnd = moment.tz('America/Chicago').endOf('day').toDate();
All three of these assume that the processeddate is in terms of UTC in your database.
You should probably also pass sql.DateTime2 instead of sql.Date.

Related

Discord JS Scheduled events

I am trying to make a discord bot that will scrape a group google calendar and remind people of upcoming events. I can get the calendar data no problem. Thing thing I don't understand is how to send a scheduled message on a discord server via discord js. This won't be a set time because it will change based on the start time of the calendar event. I'm trying to read the documentation for the GuildScheduledEvent here. But, I can't seem to figure it out/how to implement it.
I've already tried doing it from a cron task but that won't work because the event time is subject to change.
What I have so far is just a bot that will send messages when I run the script. I would really like to have it be automatic via a scheduled event.
let upcomingEvents = []; //array of calendar events
const gcpClient = authorize().then(listEvents); //getting the calendar data
const client = new Client({ intents: [GatewayIntentBits.Guilds]});
client.once(Events.ClientReady, c => {
console.log('Ready! Logged in as ', c.user.tag);
const channel = client.channels.cache.get('1049384497017266228');
upcomingEvents.forEach(element => {
channel.send(`${element.title} on ${element.readabledate}`);
});
})
client.login(TOKEN);
Again, I don't really know how to implement the Scheduled event logic.
Any help would be greatly appreciated.
As far as I understand the class ScheduledEvent doesn't represent what you need, it's for guild events like the ones explained here: https://support.discord.com/hc/en-us/articles/4409494125719-Scheduled-Events
What you need is the 'cron'-package from npm (https://www.npmjs.com/package/cron).
I modified your code to schedule a message for each upcomingEvents entry.
var CronJob = require('cron').CronJob;
let upcomingEvents = []; //array of calendar events
const gcpClient = authorize().then(listEvents);
const channel = client.channels.cache.get('1049384497017266228');
// method to convert date values to cron expressions
const dateToCron = (date) => {
const minutes = date.getMinutes();
const hours = date.getHours();
const days = date.getDate();
const months = date.getMonth() + 1;
const dayOfWeek = date.getDay();
return `${minutes} ${hours} ${days} ${months} ${dayOfWeek}`;
};
function scheduleMessage(cronExpression, msgToSend) {
var job = new CronJob(
cronExpression, // cron expression that describes when the function below is executed
function() {
channel.send(msgToSend); //insert here what you want to do at the given time
},
null,
true,
'America/Los_Angeles' //insert your server time zone here
);
}
client.once(Events.ClientReady, c => {
console.log('Ready! Logged in as ', c.user.tag);
upcomingEvents.forEach(element => { scheduleMessage(element.title, element.readabledate) });
});
client.login(TOKEN);
To get the correct cron expressions for each date value you need to convert it first, as answered in this post: https://stackoverflow.com/a/67759706/11884183
You might need to adjust some things like time zone and cronjob behavior.
If you want to keep the created cronjobs up to date you can delete them and recreate them in intervals

Calculate the difference between timestamp on google cloud function

I have a function that will run daily to check the age of every post, so how I can get the difference (in seconds) between the timestamp that I have stored in Firestore (stored as timestamp type) and the current timestamp.
exports.dailyCheckPost = functions.runWith(runtimeOptions).pubsub.schedule("28 15 * * *").timeZone('Asia/Kuala_Lumpur').onRun(async () => {
console.log("Function Running!")
const snapshot = await firestore.collection("post").where("isPublished","==",true).get();
snapshot.forEach(async (doc) => {
const data = doc.data()
var difference = admin.firestore.Timestamp.now() - data.createdAt
firestore.collection("users").doc(doc.id).set({
age : difference
},
{
merge: true
})
})
});
So...
var difference = new Date().valueOf() - data.createdAt.toDate().valueOf();
If you want to know the google real time...
admin.firestore().collection("time").doc("timeDoc").update({
updateAt:firebase.firestore.FieldValue.serverTimestamp()
}
const query = admin.firestore().collection("time").doc("timeDoc").get();
var difference = query.data().createAt.toDate().valueOf() - data.createdAt.toDate().valueOf();
However, the difference(ms) still exist the inaccuracy because the internet delay...
But... the admin object... it seems it is server code, and we usually use local time - createAt. Because our server always connects to internet, and rarely delays.

how to calculate duration with cloud functions

i want to calculate duration for a given task/event. I am using cloud functions. I have four fields in flutter app;
Start date
Start time
End date
End time
how can i calculate the duration. Please help. i am using typescript for my cloud functions.
import * as admin from 'firebase-admin'
import * as functions from 'firebase-functions'
admin.initializeApp()
export const updateCharts =
functions.firestore.document('users/{UserId}/count/{uid}')
.onWrite(async(change, _) => await updateStats(change))
async function updateStats (change:
functions.Change<functions.firestore.DocumentSnapshot>){
const chartRating = change.after.ref.parent
let title = (await chartRating.where('Title', '==', 'Game').get()).size;
//duration
const restaurantRef = chartRating.parent!
console.log('{restaurantRef.path} now has ${Title}')
await restaurantRef.update({
Title: Title,
})
// place this code where you want to measure from.
var startTime = new Date().getTime();
...
// place this code where you want to get the difference
var diff = new Date().getTime() - startTime;
Use the getTime method to get the time in total milliseconds since 1970-01-01.

Retrieving a date from Firestore in Node.js

From the Firestore documentation on saving data of supported types, I red:
var docData = {
//...
dateExample: new Date("December 10, 1815"),
//...
}
};
db.collection("data").doc("one").set(docData).then(function() {
console.log("Document successfully written!");
});
This is what I use in my Cloud Functions to save various dates to Firestore.
It works great !
My problem comes when I need to retrieve those dates and post them as String to a third party API.
As far as I understood, in Firebase/Firestore, dates are stored as a Unix Timestamp.
I couldn't find anywhere (firebase doc, stackoverflow ...) how to convert it properly to a String.
I tried unsuccessfully the following:
function timeConverter(UNIX_timestamp){
var a = new Date(UNIX_timestamp * 1000);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes();
var sec = a.getSeconds();
var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
return time;
}
admin.firestore().collection('users').doc(userId).get()
.then( (doc) => {
const user = doc.data();
const birthDate = user.birthDate;
const birthDateString = timeConverter(birthDate);
console.log(`birthDateString =${birthDateString}`);
// "birthDateString = NaN undefined NaN NaN:NaN:NaN"
});
First you can use toDate() to convert the Firebase timestamp to a Date object and then use the Date's object method toDateString() to convert it to a String.
const birthDate = user.birthDate.toDate();
const birthDateString = birthDate.toDateString();
You can also check out Moment.js, it helps a lot when dealing with Dates and displaying them.
This boils down to : how do I convert a unix timestamp to a human readable date?
There are several ways to do this but one of the easiest is to use
var readableData = new Date(doc.data().myUnixTimestamp).toLocaleDateString("en-US");
There are options for all locales. See MDN's Date.prototype.toLocaleDateString.

how to properly perform query by date in Firestore?

I am trying to make a cronjob to delete an event that has been passed by using http trigger. today is 7th September, so the event at 5 september ( 6fqmROcWD7K1pTFtXmJJ )like the picture below shall be captured in the query snapshot. but the document length is zero
here is the code I use:
export const cronJobDeletingPastEvents = functions.https.onRequest(async (request,response) => {
const dateNow = Date.now()
const pastEventsSnapshot = await admin.firestore().collection("events").where('dateTimeFinish', '<', dateNow).get()
console.log(pastEventsSnapshot.docs.length) // <---- the result is zero
// perform some actions ....
}
I don't know what went wrong in here, but I guess this is because dateNow is number, but the field dateTimeFinish in firestore is Timestamp object. but i dont know how to fix that
The following will work:
const dateNow = new Date()
const pastEventsSnapshot = await admin.firestore().collection("events").where('dateTimeFinish', '<', dateNow).get()
...
The followings would also work:
const dateNow = new Date('2018-09-07T01:25:54.000Z')
const dateNow = new Date('2018-09-07')

Resources