Giving Date parameter to mongoose query as local time - javascript

On my Node.js project I need to give query Date parameter which should be startOf current hour in local time. for example, if current local time is 2019-11-13T16:34:43.000, I should give date parameter as 2019-11-13T16:00:00.000.
For the reason I can't figure out, query accepts date only and only with New Date() function. No moment() or nothing else. I'm creating the date with moment() and then update it's hour by startOf('hour') and by format functions. The issue I live here is that, when I give this date to New Date() function inside query, New Date() function converts it to UTC time. I need my date in query to be executed as local time(Turkey Time - GMT+03:00).
const DriverPlan = analysisDB.collection('driverplans');
const nowDate = moment().startOf('hour');
console.log('nowDate: ', nowDate);
console.log('Unformatted: ', nowDate.valueOf());
const localDate = moment(nowDate).format('YYYY-MM-DDTHH:mm:ss.SSS');
console.log('localDate: ', localDate);
const courierPlans = new Promise((resolve, reject) => {
driverPlan.find({ startDateL: new Date(localDate) }).toArray((err, result) => {
if (err) {
return reject(err);
}
resolve(result);
});
});
and here is my console after the code block executed.
nowDate: moment("2019-11-13T16:00:00.000")
Unformatted: 1573650000000
localDate: 2019-11-13T16:00:00.000
So when I pass this localDate variable (which is my local time) to New Date() function inside query, Date function converts it to UTC.

In your case, I assume that all your date are given in utc because the process is running on a utc timezone machine.
I would look at https://momentjs.com/timezone/
This is useful because it accounts for the day-light saving.
var moment = require('moment-timezone');
// Create a moment with the current date
const now = moment();
//Convert to wanted timezone
now.tz('Europe/Istanbul').startOf('hour').toDate()
I would suggest using moment().toDate() instead of new Date(). This will ensure that you are using the same moment object. Unfortunately, the date object will always display in the timezone of the process.
It is possible to set the timezone via an env variable
process.env.TZ. This can be fragile depending on the usage.

Related

How can i fetch date in expressjs mysql?

I am trying to fetch the date value from a mysql server but when i printed the result;System gives an error.
In the code I can fetch the date value but when i printed it;It does not get printed correctly.(I tried to fetch a row with the value 2003-10-20 but i get 2003-10-19T21 when i printed it).
var dob_fetcher = "SELECT DOB_value FROM users WHERE Name_value='resname'";
var dob_fetcher_2 = dob_fetcher.replace("resname", req.session.name_session);
server.query(dob_fetcher_2, function (error, dob_result, fields) {
if (error) {
throw error;
} else {
var dob_value = JSON.stringify(dob_result[0]);
console.log(dob_result[0]);
}
});
JavaScript is adjusting for your local time zone which appears to be 3 hours behind UTC.
You can access the non time zone shifted values with the getUTC methods:
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCMonth()
Finally, you may want to consider a date library like Luxon which has a lot more options for handling time zones and formatting dates than what is built into JavaScript.

Taking time value and returning a value that will pass a moment().isValid() check

I am running some checks on a value that is passed into a timePicker on my react-native app, and I want to take a time value like 14:29, which is coming in as a string, and turn that into a value that will pass a moment(val).isValid() check.
How can I, for instance, just take today's date, but set the time to be this value of 14:29?
I tried this but it errors out:
let val = '14:29';
this._value = moment(new Date()).startOf(val);
Docs: set, startOf.
const input = '14:29';
const [hour, minute] = input.split(':');
const myMoment = moment()
.set({ hour, minute })
.startOf('minute');
console.log(
{ myMoment, isValid: myMoment.isValid() }
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
Note: this will respect the browser timezone meaning different users will get different moments in time, depending on their system's currently set timezone.
To set a particular timezone you might want to use .tz(). Docs: moment timezone.

What is wrong in this Firestore timestamp into Date conversion in my Angular application?

I am working on an Angular project using FireStore database and I have the following problem:
Into my Firestore database a I have documents like this:
As you can see in the previous pic the start and end fields are defined on Firestore as TimeStamp fields.
Into a service class I retrieve all these documents in this collection and I return these documents as a list of Observable by this method:
getEvents(): Observable<any[]> {
this.items = this.db.collection('calendar').valueChanges();
return this.items;
}
Then into the ngOnInit() method of my component class I do:
ngOnInit() {
this.eventService.getEvents().subscribe(events => { this.events = events.map((event) => {
console.log("START: ", event.start);
//var date = new Date(event.start);
var date = new Date(0); // The 0 there is the key, which sets the date to the epoch
date.setUTCSeconds(event.start);
var hour = date.getHours();
console.log("START DATE: ", date);
console.log("START HOUR: ", hour);
// ...
}
and here my problem: the value of the event.start is not a date but an object like this (this is the console.log() output):
START: t {seconds: 1487257200, nanoseconds: 0}
From what I know this object represents my date but how can I convert it again into a Date object.
As you can see I tried doing in this way:
var date = new Date(0); // The 0 there is the key, which sets the date to the epoch
date.setUTCSeconds(event.start);
but doing in this way I am obtaining a wrong date, in fact I am obtaining:
START DATE: Sun Feb 16 3986 07:00:00 GMT-0800 (Ora standard del Pacifico USA)
the month and the day (Feb 16) are correct but the year is totally wrong (3986 instead 2017).
What is wrong? What am I missing? What is the correct way to obtain a Date object from the retrieved Firestore Timestamp?
because firestore timestamp is actually different from normal JS Date().
in order to get JS date from timestamp you can use the method that firestore has on its timestamps.
in your code:
event.start should be event.start.toDate()
PS. for your IDE to know the methods that work on that object. Typescript must know the type of object it is.
so for example if you are using AngularFire and you make a call to get a document then the type will already be there and your IDE will show available methods. But if the object type is generic like "any" then your IDE wont give available methods. and might throw an error like "method doesn't exist on type any"
You can use the Timestamps toDate() function and map the observable including arrays to Dates and return those objects:
// Create a custom type to tidy it up. Would recommend creating that in another file.
// Here more on type aliases: https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases
type ReturnType = {start: Date, end: Date, title: string};
// Change the function to return the created type
getEvents(): Observable<ReturnType[]> {
this.items = this.db.collection('calendar').valueChanges()
.pipe(map(tArr => // Use pipe to transform an observable or subject to something else, without subscribing. Check out: https://rxjs-dev.firebaseapp.com/guide/operators
tArr.map(t => { // Map the array of objects including Timestamps to dates
t.start = t.start.toDate();
t.end = t.end.toDate();
return t;
})
)) as Observable<ReturnType[]>;
return this.items;
}
You construct you JS Date incorrectly.
Correct way to create date is passing milliseconds to it.
var date = new Date(event.start.seconds * 1000);

How to check if timestamp of SQL fetched dateTime object is older than another one with moment.JS?

I query a dateTime object from PostgreSQL DB using an AJAX call which returns the following format:
2019-12-13T22:59:59Z // print type of: `undefined`
I now want to compare the timestamp of that object with the current time now and fire a function if the timestamp is not older than 5 seconds compared to the current time.
My idea is to calculate the difference in seconds and check the result for <> 5.
But how can I convert the database fetched dateTime object into a moment object to be able to compare them?
Edit:
Due to the conclusions from the comments provided, I changed my logic and end up with the following problem:
I have a timestamp in SQL which changes secondly. I fetch this timestamp with AJAX and would like to fire a function if the new timestamp is not older than 5 seconds than the previous one.
I set up moment.js objects to calculate the difference. Now my problem is that on the first iteration latestTick is not defined.
How can i design the loop that it compares both timestamps and always updates the latestTick with the lastTick for the next iteration (and also won't error on the first iteration)?
Javascript:
Ajax call...
[...]
lastTick = response[0].fields.account_lastTick.toString()
lastTick1 = lastTick.slice(0, 10)
lastTick2 = lastTick.slice(11, 19)
lastTick = lastTick1 + ' ' + lastTick2
lastTick = moment(lastTick, 'YYYY-MM-DD hh:mm:ss')
if ((lastTick.diff(latestTick, 'seconds')) != 0) {
console.log('not Zero')
} else {
console.log('Zero')
}
latestTick = moment(lastTick, 'YYYY-MM-DD hh:mm:ss')
[...]
To give you an idea on how to compare time in Moment.js. you can do this
import moment from "moment"
const dateTimeStr = "2019-12-13T22:59:59Z" // your DB already includes timezone in the response (UTC+00:00)
const dateTimeMoment = moment(dateTimeStr)
const next5MinsMoment = moment().add(5, 'minutes')
if(dateTimeMoment.isBefore(next5MinsMoment)) {
// fire function call
}

Issues with Date() when using JSON.stringify() and JSON.parse()

I am trying to calculate the difference between two times using JavaScript. It's just basic math but I seem to have some issues with that while using JSON.stringify() and JSON.parse().
If you're wondering why am I applying the JSON.stringify() function to the date, it's because I using local storage to store some data on the client side and use it whenever the client lands on my website again ( it's faster that way rather than making more requests to the server ). That data usually updates once in a while ( I'm grabbing the data through API from another website ), so I set up a data_update variable and I'm storing it together with the other data.
That way I'm grabbing the stored data from the local storage and check if the difference between data_update ( which is a date / time ) and the time / date when the check it's made and see if it's greater than a week / day /etc .
So that is the reason why I'm using the JSON functions. My problem is that when I'm parsing the data from the local storage, the date seems to be different from a Date() object.
I'm trying to do the next operation per say :
var x = JSON.parse(JSON.stringify(new Date()));
var y = JSON.parse(this.get_local_storage_data(this.data_cache_key)); // the data object stored on local storage
var q = y.data_update; // this is the variable where the Date() was stored
console.log(Math.floor((x-q)/1000));
The above will return null. Also when I want to see the Math.floor(x) result, it returns null again.
So what can I do in this situation ? Is there a fix for this ?
If you look at the output of JSON.stringify for a Date, you'll see that:
JSON.stringify(new Date())
Results in a string. JSON does not have a primitive representation of Date objects that JSON.parse will turn back into a Date object automatically.
The Date object's constructor can take a date string, so you can turn those string values back into dates by doing:
var x = new Date(JSON.parse(JSON.stringify(new Date())));
Then the arithmetic will work.
x = new Date(JSON.parse(JSON.stringify(new Date())))
y = new Date(JSON.parse(JSON.stringify(new Date())))
y - x
=> 982
JSON.stringify(new Date())
returns
"2013-10-06T15:32:18.605Z"
Thank God is: Date.prototype.toISOString()
As the recommended answer suggests, the date is simply converted to a string when using JSON.stringify.
Another approach that would maybe fit this use case is to store the time in milliseconds using Date.now():
// Date.now() instead of new Date()
const millis = Date.now();
console.log(millis);
// same output as input
console.log(JSON.parse(JSON.stringify(millis)));
That way you can be sure that what goes into JSON.stringify comes out the same when using JSON.parse.
This also makes it easy to compare dates, if you have two millisecond values, using < and >.
Plus you can convert the milliseconds to a date at any time (usually before you render it to the user):
const millis = Date.now();
console.log(millis);
console.log(new Date(millis));
NOTE: using milliseconds as your date representation is usually not recommended, at least not in your database: https://stackoverflow.com/a/48974248/10551293.

Categories

Resources