Timezone issue in javascript Date object - javascript

I am working on an employee time tracking application with its backend on node.js. The problem is when the site is hosted locally it registers the time in gmt +05:30 which is correct as i live in india but when i hosted the site on heroku server (which i think the heroku's server time zone is set to 00:00) and accesses it from same computer. then, it registers the time in gmt +00:00.
Now what i want is that when its hosted on heroku server it should know the time zone of the user (Example if user resides in Los Angeles and creates an entry. then, it should register the entry in GMT-7 timezone)
Screenshot
Code
const postSchema = {
username: String,
entry: String,
rawEntry: Number,
exit: String,
rawExit: Number,
duration: String,
complete: Boolean,
createdAt: {
type: Date,
default: Date.now()
}
};
logEntry Route
app.get('/logEntry', function(req, res) {
if (req.isAuthenticated()) {
const t = new Date();
const now = date.format(t, 'DD/MMM/YYYY ddd hh:mm:ss A Z');
const rawNow = Date.now();
const post = new Post({
username: nameUser,
entry: now,
rawEntry: rawNow,
complete: false
});
post.save(function(err) {
if (err) {
console.log(err);
}
res.redirect('/logged');
});
} else {
res.redirect('/');
}
});

This is a very common problem that we face with timezone.
Client side get getTimezoneOffset and add or remove seconds that are over.
const d = new Date();
const n = d.getTimezoneOffset();
console.log("your PC or laptop timezone more or less in seconds", n); // -330
So, when you will run this code in local that time as you told you are having gmt +05:30 getTimezoneOffset will output -330 sec means 5 hour and 30 mins.
So you can remove these seconds from the current time and set accordingly.
or
You can use in build javascript function
const d1 = new Date();
console.log(d1); //Thu Aug 29 2019 17:56:14 GMT+0530
d1.toUTCString(); // Thu, 29 Aug 2019 12:26:39 GMT
Check the differance is +5:30 hours.

I solved this problem by executing new Date() on the client side and then passing in url to the server for further action.
Client side code =>
<button onclick="createLogin()" class="btn btn-outline-primary btn-lg btn-block entryBtn">
CREATE LOGIN ENTRY
</button>
<script>
function createLogin() {
let t = new Date();
console.log(t);
let url = '/logEntry/' + t;
window.location = url;
}
</script>
Server side code =>
app.get('/logEntry/:date', function(req, res) {
if (req.isAuthenticated()) {
const now = req.params.date;
const nowDayTime = now.substring(0, 25);
const timeZone = now.substring(25, now.length);
const rawNow = Date.now();
const post = new Post({
username: nameUser,
entryDayTime: nowDayTime,
entryTimeZone: timeZone,
rawEntry: rawNow,
complete: false
});
post.save(function(err) {
if (err) {
console.log(err);
}
res.redirect('/logged');
});
} else {
res.redirect('/');
}
});

Related

how to update posted time locally in node.js

I wanna update time for post when user created post.
i tried some method but didnt get expected results.
Note - im storing created post in array. (locally)
const posts = [];
const addedDate = new Date();
const addedTime = addedDate.getMinutes();
exports.getIndex = (req, res, next) => {
res.render('index', {
pageTitle: 'NewsFeed',
path: '/',
post: posts,
time: addedTime,
});
};
exports.getPost = (req, res, next) => {
res.render('post', {
pageTitle: 'Create Post',
path: '/post',
});
};
exports.postAddPost = (req, res, next) => {
posts.unshift({ title: req.body.title });
res.redirect('/');
};
Here is the pic of post
time is not updating
i want to time auto update
like
1min ago - 1hr ago - 1 day ago
https://i.stack.imgur.com/eTD02.png
Use momentJS library. they have every format you'd need. The one you want is FromNow.
It seems like you create "addedDate" once when you run your application using the current time. When you show your news feed, you pass along the minutes of the time that you started your application.
I assume that you're trying to display when a post was created. In this case you should add the current time to your post object:
exports.postAddPost = (req, res, next) => {
posts.unshift({ title: req.body.title, added: new Date() });
res.redirect('/');
};
Then in your template you would iterate over the posts array that you pass as "post" and access the properties via "post.title" and "post.added".
I'm not sure what you had in mind regarding the minutes. If you intended to display something like "posted 5 minutes ago", then you could create another Date in your template and compare it with the "added" property of your post to figure out the difference.
The difference can be calculated fairly easily with vanilla JavaScript, you can just subtract two Date objects and get the difference in milliseconds:
const post = {
title: 'Title',
added: new Date(),
};
// some time later
const now = new Date();
const milliseconds = now - post.added;
const seconds = ms / 1000;
const minutes = seconds / 60;
And so on.

React datetime format not working when sending date as url parameter to API

i am trying to pass date time value as url parameter to backend java api , I am using GET method to send request. But at the api end i am getting only part of date time string, other part of date time string is cutting off.
my react code
const handleStartDate = date => {
setStartDate(date);
const formattedDttm = format(date, "dd.MM.yyyy H:mm:ss", { timeZone: "Asia/Kolkata" });
console.log(formattedDttm);
DataService.findByDttmOfSale(formattedDttm)
.then(response => {
Entry.price = response.data.price;
}).catch(e => {
if (e.response && e.response.data) {
setMessage(e.response.data.message);
setAlertHeading("Error!");
setAlertVariant("danger");
setShow(true);
console.log(e.response.data.message); // some reason error message
}
console.log(e);
});
};
At java backend
#GetMapping("/FromDttmOfSale/{dttm_of_sale}")
public TestMO getFromDateTimeOfSale(#PathVariable(value = "dttm_of_sale") String
dateTimeOfSale) throws Exception {
System.out.println(" get mo from date time of sale date value is = " + dateTimeOfSale);
TestMO testMO = fuelService.getFuelPriceByDateTime(dateTimeOfSale);
return testMO ;
}
the date i entered from react js is of format 11/10/2020 8:42 AM where as at backend i am getting only part of the date string as date time of sale date value is = 11.10
same where during conversion the date string is getting stripped off. i have tried changing the format also but getting same error
Might be better to pass the date as a string and then format it to date on the backend.
i have changed my date param from 11/10/2020 8:42 AM to 11 10 2020 8:42 AM and it started working. seems like there is limitation sending special characters in url
I had the same error and i solved it using two options, first using the moment library and the second that I consider better converting the date toISOString before sending it to the backend.
export async function getAssessmentsByDate(dateInit, dateEnd, clientId) {
try {
const response = await getApi().get(
`/assessment/${clientId}?dateInit=${dateInit.toISOString()}&dateEnd=${dateEnd.toISOString()}`,
{}
);
return response;
} catch (error) {
return { status: 400, message: 'Cant..' };
}
}
In the backend (nodejs) I receive it this way. I recommend you validate the string before using it. It worked perfectly for me.
const getClientAssessmentByDate = async (req, res) => {
try {
const clientId = parseInt(req.params.id);
const dateInit = req.query.dateInit;
const dateEnd = req.query.dateEnd;
/** .... */
/** 3. find evaluations */
const results = await AssessmentResult.findAll({
where: {
createdAt: {
[Op.between]: [dateInit, dateEnd]
}
}
})
/** .... */
} catch (e) {
return res.status(500).send('error processing request');
}
}

dialogflow how to play the next time available from google calendar

how are you? English are my native language, so I apologize right away.
what I have is a bot in the dialogflow, which with some interactions marks events on the agenda.
an example:
Bot: hello welcome to the hairdresser, would you like to make an appointment?
User: Yes
Bot: What's your name?
User: Welyson
Bot: What day would you like?
User: tomorrow
Bot: What time?
User: 3pm
If you have space on the google calendar
Bot: Okay, you were scheduled for February 21st at 3pm
-If you don't have space on the google calendar
Bot: Oops, it appears that we have no vacancies for that day or time, type check to try another time.
Where I got the code as an example
The code below does this:
'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
// Enter your calendar ID below and service account JSON below
const calendarId = "id google agenda ";
const serviceAccount = {json file}; // Starts with {"type": "service_account",...
// Set up Google Calendar Service account credentials
const serviceAccountAuth = new google.auth.JWT({
email: serviceAccount.client_email,
key: serviceAccount.private_key,
scopes: 'https://www.googleapis.com/auth/calendar'
});
const calendar = google.calendar('v3');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements
const timeZoneOffset = '-03:00';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
const appointment_nome = agent.parameters.nome;
function makeAppointment (agent) {
const dateTimeStart = new Date(Date.parse(agent.parameters.date.split('T')[0] + 'T' + agent.parameters.time.split('T')[1].split('-')[0] + timeZoneOffset));
const dateTimeEnd = new Date(new Date(dateTimeStart).setHours(dateTimeStart.getHours() + 1));
const agendamentoString = FormtData(new Date(agent.parameters.date.split('T')[0])) + " às " + agent.parameters.time.split('T')[1].split('-')[0];
// Check the availibility of the time, and make an appointment if there is time on the calendar
return createCalendarEvent(dateTimeStart, dateTimeEnd, appointment_nome).then(() => {
let mensagem = `Okay, you were scheduled for *${agendamentoString}* ✅.`;
response.json({"fulfillmentText": mensagem});
}).catch(() => {
let mensagem = `Oops, it appears that we have no vacancies for that day or time, type **check** to try another time.`;
response.json({"fulfillmentText": mensagem});
});
}
let intentMap = new Map();
//intentMap.set('Schedule Appointment', makeAppointment);
intentMap.set('Default Welcome Intent - yes', makeAppointment);
agent.handleRequest(intentMap);
});
function createCalendarEvent (dateTimeStart, dateTimeEnd, appointment_nome) {
return new Promise((resolve, reject) => {
calendar.events.list({
auth: serviceAccountAuth, // List events for time period
calendarId: calendarId,
timeMin: dateTimeStart.toISOString(),
timeMax: dateTimeEnd.toISOString()
}, (err, calendarResponse) => {
// Check if there is a event already on the Calendar
if (err || calendarResponse.data.items.length > 0) {
reject(err || new Error('Requested time conflicts with another appointment'));
} else {
// Create event for the requested time period
calendar.events.insert({ auth: serviceAccountAuth,
calendarId: calendarId,
resource: {summary:"Cliente: " + appointment_nome, description: "Cliente: " + appointment_nome,
start: {dateTime: dateTimeStart},
end: {dateTime: dateTimeEnd}}
}, (err, event) => {
err ? reject(err) : resolve(event);
}
);
}
});
});
}
function FormtData(date){
var nomesMes = [
"Janeiro", "Fevereiro", "Março",
"Abril", "Maio", "Junho","Julho",
"Agosto", "Setembro", "Outubro",
"Novembro", "Dezembro"
];
var dia = date.getDate();
var mesIndex = date.getMonth();
var ano = date.getFullYear();
return dia + ' ' + nomesMes[mesIndex];
}
But the problem is that if my schedule has too many times scheduled, the schedule will become tiring for the user!
I thought of something, like
Bot: Would you like to schedule a haircut?
User: yes
Bot: How about February 21st at 1 pm?
-If the user agrees the time is marked in the agenda:
User: Yes
Bot: Okay, you were scheduled for February 21st at 1pm
-If the user disagrees he goes to the next available time:
User: No
Bot: How about February 21st at 2 pm?
I tried something with the CalDAV API to read the google calendar, I didn't get any progress
Does anyone have any idea how I would do this? Thank you very much in advance

OTP generation in nodejs using speakeasy :set expiry time

I am using https://www.npmjs.com/package/speakeasy to generate OTP and i would like the expiry to 10 minutes.
Here is the code for generation
const generateOtp = function generateOtp() {
let token = speakeasy.totp({
secret:process.env.OTP_KEY,
encoding: 'base32',
digits:4,
window:10
});
return token;
}
Verify OTP
const verifyOtp = function verifyOtp(token){
let expiry = speakeasy.totp.verify({
secret:process.env.OTP_KEY,
encoding: 'base32',
token: token,
window:10
});
console.log(expiry)
}
But I don't know how to set the expiry to 10 minutes??
Reading the documentation you can find out that the base step is 30 seconds, so if you want to have an expiration time of 10 minutes you need to set up the step to 60. Then, using the verifyDelta method you should be able to check if the token expired.
const generateOtp = function generateOtp() {
let token = speakeasy.totp({
secret:process.env.OTP_KEY,
encoding: 'base32',
digits:4,
step: 60,
window:10
});
return token;
}
const verifyOtp = function verifyOtp(token){
let expiry = speakeasy.totp.verifyDelta({
secret:process.env.OTP_KEY,
encoding: 'base32',
token: token,
step: 60,
window:10
});
console.log(expiry)
}

Query Mongo for all entries added today (newbie)

I'm trying to query Mongo for all entries added today. For example, if I added something at 9 am, I only want that back and not something added at 9 pm last night.
I'm unsure how to properly format the query.
const db = require('../models');
const now = new Date();
const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
// Defining methods for the mealsController
module.exports = {
find(req, res) {
db
.Meal
.find({created_on: {$gte: startOfToday}})
},
findAll(req, res) {
db
.Meal
.find(req.query)
.sort({ date: -1 })
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
findById(req, res) {
db
.Meal
.findById(req.params.id)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
I can help you with a precise query if you share how you are storing data in db.
From your question, what i am guessing you are looking for is retrieving documents inserted after a certain time.
ObjectId.getTimestamp() will help you in this case. in Mongo, every insert has a time stamp associated with it. eg. ObjectId("5a6d75590827a11b6016f470").getTimestamp()
returned
ISODate("2018-01-28T07:01:45Z")
To get the Object id of a document, var a = db.collection.find(<condition>).toArray();a[0]._id then prints ObjectId("5a6d75560827a11b6016f46e")
so you can compare which documents were inserted after a certain date or time using this.
GL :)

Categories

Resources