Conflicting dates in mongoose and express.js - javascript

The problem occurs when I declare my schema with type Date rather than String.
Case I:
var MySchema = new Schema({
created_at: {type: String, default: ''}
});
With this shema declaration I use moment.js moment-timezone module for declaring current time in Asia/Kolkata timezone.
var tmoment = require('moment-timezone');
var currentTime = tmoment().tz('Asia/Kolkata').format('llll');
And I am able to get the correct time.
Case II:
var MySchema = new Schema({
created_at: {type: Date, default: ''}
});
With this shema declaration I use moment.js moment-timezone module for declaring current time in Asia/Kolkata timezone.
var tmoment = require('moment-timezone');
var currentTime = tmoment().tz('Asia/Kolkata').format('llll');
But now the time is not coming according to the timezone. I even tried with the following declaration
var tmoment = require('moment-timezone');
var currentTime = tmoment().tz('Asia/Kolkata').format();
But could not find a solution.

When you are saving dates to a mongo database, you can simply save a javascript Date object regardless of timezone. (Using the Date type as in case 2.) Then you would use moment to display the date in whatever timezone you require.
To save the object:
var id = ...
var saveReq = new RequestModel({ _id: id, created_at: new Date() });
saveReq.save(function (err, result) {
// ...
});
To read the object from the database, and then display the localized date string:
var tmoment = require('moment-timezone');
RequestModel.findOne({_id: id}, function (err, doc) {
if(err) {} // ...
var created = doc.created_at;
var display = tmoment(created).tz('Asia/Kolkata').format('llll');
console.log(display);
});

change server timezone to your local timezone.

Related

Mongoose lte method not working for moment

I am fetching Date saved in db. Then, I am doing a small date maths to substract date from today from 3, which is giving me Date in Format - (DD-MM-YYYY). Date saved in db format is also same - (DD-MM-YYYY). Can anyone help me out in validating $lte for that date. I am not getting any log for DipData.
nodeCron.schedule("* * * * *", async function () {
var DateNow = await moment().subtract(3, "days").format("DD-MM-YYYY");
console.log("Test Date Cron",DateNow);
console.log("-->",new Date(DateNow.format("DD-MM-YYYY")));
let DipData = await userModel.find({}, { LastAppOpenedTime: { $lte : new Date(DateNow.format("DD-MM-YYYY")) }})
console.log("-----DipData ------->", DipData);
});
First thing you need to identify if there is date which is stored in document of mongo collection is string or regular date format or epoch format. If it's string the query may gives not accurate result. If there is date format or epoch format, you can easily queried your result with proper result.
Therefore in case if there is string in LastAppOpenedTime document key you can have query with $toDate under find query.
If key is not in string format in stored document following code will work.
var DateNow = moment().subtract(3, "days");
const DipData = await userModel.find({ LastAppOpenedTime: { $lte: new Date(DateNow) } });
For the above two scenario would work if your query is in accurate form like removing the first empty braces.
userModel.find({}, { LastAppOpenedTime: { $lte : new Date(DateNow) }})
to
userModel.find({ LastAppOpenedTime: { $lte : new Date(DateNow) }})
Hello I got this working by making a few changes
const DateNow = await moment().subtract(3, "days");
console.log("Test Date Cron", DateNow);
console.log("-->", new Date(DateNow));
const DipData = await userModel.find({ createdAt: { $lte: new Date(DateNow) } });
console.log("-----DipData ------->", DipData);
res.status(200).json({ success: true, message: "Request was successful", DipData });
I noticed you had the .format("DD-MM-YYYY") at the end of your moment function but it returned a string that couldn't be converted with the new Date(DateNow). I removed mine when testing as the response from the moment was working fine without it.
And also I updated your userModel.find({}, { LastAppOpenedTime: { $lte : new Date(DateNow.format("DD-MM-YYYY")) }}) to remove the first empty {}. So you would have userModel.find({ createdAt: { $lte: new Date(DateNow) } });

Firestore/Javascript: How to get document data using timestamps?

I'm trying to create a line graph for my project. To accomplish this I need two date inputs from a user. From there my backend takes the inputs converts it to a javascript date object.
My problem is when I'm trying to convert the date objects to a firestore timestamp I get this error.
TypeError: t.getTime is not a function
at Function.ho.fromDate (timestamp.ts:27)
at Object.next (generateReportDateRange.php:158)
at subscribe.ts:104
at subscribe.ts:233
line (generateReportDateRange.php:158) pinpoints to this code:
var toTimeStampOne = firebase.firestore.Timestamp.fromDate(dateIdOne);
What that code does is to convert the date object to a firestore timestamp object. From there I am supposed to use toTimeStampOne as a query to get certain data from documents
here is the backend end code that may be related to the problem:
var dateIdOne = sessionStorage.getItem("dateOne");
var dateIdTwo = sessionStorage.getItem("dateTwo");
var dateSetArray = [];
var dataCal = [];
console.log(dateIdOne); //OUTPUT: Fri Mar 06 2020 08:00:00 GMT+0800 (Philippine Standard Time)
console.log(dateIdTwo); //OUTPUT: Tue Mar 10 2020 08:00:00 GMT+0800 (Philippine Standard Time)
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.userId = user.uid;
} //stores the user id in variable
var toTimeStampOne = firebase.firestore.Timestamp.fromDate(dateIdOne);
var toTimeStampTwo = firebase.firestore.Timestamp.fromDate(dateIdTwo);
var dateSetArray = [];
var dataCal = [];
let userRef1 = firebase.firestore().collection("users").doc(userId).collection("glucose")
.where("dateAdded", ">=", toTimeStampOne)
.where("dateAdded", "<=", toTimeStampTwo)
.limit(7);
return userRef1.get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
this.dateSet = doc.data().bgReading;
dateSetArray.push(dateSet);
this.calDateAdded = doc.data().dateAdded.toDate();
const options = {
month: 'short',
day: 'numeric',
year: 'numeric'
};
const date = new Date(calDateAdded);
const americanDate = new Intl.DateTimeFormat('en-us', options).format(date);
dataCal.push(americanDate);
});
});
});
EDIT
here is the process of the conversion
//get date input from the forms and converts it to a js date object already
var data = {
dateOne: new Date($('#dateRangeOne').val()),
dateTwo: new Date($('#dateRangeTwo').val()),
};
//stores the date object to a session storage
sessionStorage.setItem("dateOne", data.dateOne);
sessionStorage.setItem("dateTwo", data.dateTwo);
You need to do
var dateIdOne = new Date(sessionStorage.getItem("dateOne"));
var dateIdTwo = new Date(sessionStorage.getItem("dateTwo"));
because
sessionStorage.setItem("dateOne", data.dateOne);
converts date to toString()
and
fromDate is a static method from the static Timestamp class from Firebase. If you want to store a field as a timestamp in Firestore, you'll have to send a JavaScript Date object or a Firestore Timestamp object as the value of the field
I'm going to go ahead and make the call that your "date" object is not actually a JavaScript Date object. It's probably just a formatted string. You won't be able to work with this very effectively if you're trying to query Firestore timestamp fields.
You're probably going to need to change whatever the source of data is that's feeding these lines of code:
var dateIdOne = sessionStorage.getItem("dateOne");
var dateIdTwo = sessionStorage.getItem("dateTwo");
You'll need to make sure that sessionStorage.getItem returns something suitable for querying Firestore. That could be a proper date object, or some unix time in milliseconds that you can easily convert into a Timestamp.
I like to create the full code structure but I already marked an answer. Regardless I will post the code here because it might help other people.
Get input value from forms and use sessionStorage to carry it over to another page
<script>
(function(){
$('#dateForm').on('submit', async function (e) {
e.preventDefault();
var data = {
dateOne: $('#dateRangeOne').val(),
dateTwo: $('#dateRangeTwo').val(),//get date input
};
if(data.dateOne.getTime() == data.dateTwo.getTime()){
alert("Please input a valid date range! Use the specific date generator to generate a daily report");
window.location.href = "generateReport.php";
}
else if(data.dateOne.getTime() > data.dateTwo.getTime()){
alert("Please input a valid date range!");
window.location.href = "generateReport.php";
}
else{
firebase.auth().onAuthStateChanged(function(user){
if(user){
this.userId = user.uid; //stores the userid
console.log(userId);
}
sessionStorage.setItem("dateOne", data.dateOne);
sessionStorage.setItem("dateTwo", data.dateTwo);
setTimeout(function(){
window.location.href = "generateReportDateRange.php";
}, 3000);
});
}
});
})
();
</script>
The query code (Getting document data based on two Firestore timestamp objects)
<script>
var dateIdOne = new Date(sessionStorage.getItem("dateOne"));
var dateIdTwo = new Date(sessionStorage.getItem("dateTwo"));
firebase.auth().onAuthStateChanged(user => {
if(user){
this.userId = user.uid;
} //stores the user id in variable
var toTimeStampOne = firebase.firestore.Timestamp.fromDate(dateIdOne);
var toTimeStampTwo = firebase.firestore.Timestamp.fromDate(dateIdTwo);
let userRef1 = firebase.firestore().collection("users").doc(userId).collection("glucose")
.where("dateAdded", ">=", toTimeStampOne)
.where("dateAdded", "<=", toTimeStampTwo)
.limit(7);
//PERFORM GET DOC DATA HERE
});
</script>

Insert wrong date in MongoDB

I am tring to save dates in my MongoDB table using C#.
Here is a JavaScript logic that send data using Ajax to C# controller
$(function ($, w, d) {
var _user = {}
//var time = moment("2016-04-02", "YYYYMMDD").fromNow()
//var bime = moment().endOf('day').fromNow();
//var crime = moment("20120620", "YYYYMMDD").fromNow();
// document.getElementById('time').innerHTML = time;
var obj = {};
var holidaylist = ["Mar-31-2018", "Apr-01-2018","Apr-04-2018","Apr-07-2018","Apr-08-2018"];
var startdate = new Date("Apr-02-2018");
obj.endDate = "Apr-06-2018";
obj.holidaylist = holidaylist;
obj.NumberOfCount = 9;
CallAjax("POST", '/LeaveManagement/', 'checkleavelogic', obj, onsuccessaddemployee, '');
here is the C# logic that saves the data in MongoDB:
public JsonResult checkLeaveLogic(LeaveLogicModel leaveLogic)
{
string strconnectiomstring = "mongodb://10.10.32.125:27017";
MongoClient Client = new MongoClient(strconnectiomstring);
var DB = Client.GetDatabase("TimeClock");
List<DateTime> leavesDate = new List<DateTime>();
var collection = DB.GetCollection<LeaveLogicModel>("leaves1");
collection.InsertOne(leaveLogic);
}
Now this is the MongoDB table that saves as a previous date.
Here you can see that my StartDate is Apr-02-2018 but it saves as Apr-01-2018 and for all date it is the same.
Can someone tell me where I am wrong?
When you create new dates with just date or date and time, it usually creates them in the same timezone as the program is.
So if you dont specify the timezone, it becomes the timezone the server is in. When you save to Mongo, the Date is serialized to UTC -> zero timezone.
Create the dates with +00:00 timezone and you should have consistent data.
It's a good practice to set your datetimes to UTC, however if you want to convert it, you can use something like this.
var date = DateTime.UtcNow;
TimeZoneInfo.ConvertTime(date, TimeZoneInfo.Local);

Getting "Invalid Date" when passing dynamic date in IE 11 only in Javascript

Creating date using dynamically generated date string throws invalid date message only in IE11.
Example
var today = new Date();
var ag_endDate = new Date(today).toLocaleDateString('en-US');
var final = new Date(ag_endDate);
console.log(final);
try this
var dateObj = new Date();
var usFormatDate = dateObj.toLocaleDateString('en-US');
console.log( usFormatDate );
sorry, my bad! date constructor does take date Object as parameter.
However, if your intention is to simply get the formatted date in en-US locale, then you don't have to create another date object for the same.

Google Form on Submit get values and format the time

I am using Google Apps Script with a Google form. When the user submits the Google Form I get a value from a question. I then take that value and make it a date object, from what I saw on this post about daylight savings I use that to determine the timezone. I run the date object through Utilities.formatDate and want to get the correctly formatted date.
example: 9:00 AM
But instead I am getting a completely different time than expected.
My question is: Can someone help me understand why the below code is outputting a time that is 3 hours different?
function onSubmit(e) {
var values = e.values;
Logger.log(values);
try {
var start1 = new Date(values[3]);
var startN = new Date(start1).toString().substr(25,6)+"00";
var startT = Utilities.formatDate(start1, startN, "h:mm a");
Logger.log(startT);
} catch(error) {
Logger.log(error);
}
}
The assumption that Utilities formatDate does not support GMT... parameter is not true.
The post you mentioned in reference is used to get calendar events and is a useful way to get the right value when you get events from another daylight saving period (getting the TZ info from the calendar event itself), for example events for next month will be in "summer time" while we are still in "winter time"...
Your issue might come from different sources depending on time zone settings of your script vs timezone of the source. Could you describe the exact configuration in which you use this script ?
In the mean time, here is a small code that demonstrates how the code is working + the logger results :
function testOnSubmit() {
var eventInfo = {};
var values = {};
values['3'] = new Date();
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
onSubmit(eventInfo);
}
function onSubmit(e) {
var values = e.values;
try {
var start1 = new Date(values[3]);
Logger.log('onSubmit log results : \n');
Logger.log('start1 = '+start1)
var startN = new Date(start1).toString().substr(25,6)+"00";
Logger.log('startN = '+startN);
var startT = Utilities.formatDate(start1, startN, "h:mm a");
Logger.log('result in timeZone = '+startT);
} catch(error) {
Logger.log(error);
}
}
EDIT : additionally, about the 30 and 45' offset, this can easily be solved by changing the substring length like this :
var startN = new Date(start1).toString().substr(25,8);
the result is the same, I had to use the other version a couple of years ago because Google changed the Utilities.formatDate method at some moment (issue 2204) but this has been fixed.
EDIT 2 : on the same subject, both methods actually return the same result, the GMT string has only the advantage that you don't have to know the exact timezone name... there is also the Session.getScriptTimeZone() method. Below is a demo script that shows the resulst for 2 dates in January and July along with the log results :
function testOnSubmit() {
var eventInfo = {};
var values = {};
values['3'] = new Date(2014,0,1,8,0,0,0);
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
onSubmit(eventInfo);
values['3'] = new Date(2014,6,1,8,0,0,0);
eventInfo['values'] = values;
Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n');
onSubmit(eventInfo);
}
function onSubmit(e) {
var values = e.values;
var start1 = new Date(values[3]);
Logger.log('onSubmit log results : ');
Logger.log('start1 = '+start1)
var startN = new Date(start1).toString().substr(25,8);
Logger.log('startN = '+startN);
Logger.log('result in timeZone using GMT string = '+Utilities.formatDate(start1, startN, "MMM,d h:mm a"));
Logger.log('result in timeZone using Joda.org string = '+Utilities.formatDate(start1, 'Europe/Brussels', "MMM,d h:mm a"));
Logger.log('result in timeZone using Session.getScriptTimeZone() = '+Utilities.formatDate(start1, Session.getScriptTimeZone(), "MMM,d h:mm a")+'\n');
}
Note also that the Logger has its own way to show the date object value ! it uses ISO 8601 time format which is UTC value.
Try this instead:
var timeZone = Session.getScriptTimeZone();
var startT = Utilities.formatDate(start1, timeZone, "h:mm a");
The Utilities.formatDate function expects a time zone that is a valid IANA time zone (such as America/Los_Angeles), not a GMT offset like GMT+0700.
I am making the assumption that Session.getScriptTimeZone() returns the appropriate zone. If not, then you might need to hard-code a specific zone, or use a different function to determine it.
Additionally, the +"00" in the script you had was assuming that all time zones use whole-hour offsets. In reality, there are several that have 30-minute or 45-minute offsets.

Categories

Resources