How to update Firestore Timestamp to a future value - javascript

We have a check-in and check-out component in our web app that simply uses firebase timestamps. However, we need the ability to edit those timestamps in the event someone makes a mistake.
checkInTimeStamp: fb.firestore.FieldValue.serverTimestamp("17:00") simply returns the current time.
Instead of 17:00, what object do we need to pass through the function to get the correct timestamp?

The serverTimestamp() generates current timestamp on server side. You can use a Date object instead to store a future date:
const futureDate = new Date();
// update date to future time
futureDate.setDate(futureDate.getDate() + 5);
db.document('col/doc').set({ checkInTimeStamp: futureDate })
Checkout other method like setDate() in MDN docs.

Related

MongoDB Stored my date with the wrong time

I recently tried to assign a new date in MongoDB, but I have a problem with that, it stored the date I give but it's not correct
userSchema.methods.createPasswordResetToken = async function () {
this.passwordResetToken = crypto.randomBytes(20).toString('hex')
this.passwordResetExpires = moment().format(this.createAt)
await this.save()
console.log(moment().format(this.createAt)) // 2021-12-21T19:01:54+02:00
console.log(this.passwordResetExpires) // 2021-12-21T17:01:54.000Z
return { token: this.passwordResetToken, userId: this._id }
}
mongoDb remove 2 hours when storing it
and when I try to catch the type of two values
I got
console.log(moment().format(this.createAt)) // string
console.log(this.passwordResetExpires) // object
:
user Schema
...
passwordResetToken: String,
passwordResetExpires: Date
...
From the docs:
MongoDB stores times in UTC by default, and will convert any local time representations into this form. Applications that must operate or report on some unmodified local time value may store the time zone alongside the UTC timestamp, and compute the original local time in their application logic.
It seems your server just sits in GMT timezone ( utc +2, you could also see it from your date value // 2021-12-21T19:01:54+02:00 ). I would usually offer some hacky way to get around the issue but this is actually a best practice. Hence I recommend you do your date calculations in UTC and not in machine time.
note your other date is in UTC (2021-12-21T17:01:54.000Z), make sure your comparing apples to apples.

Get JavaScript local date from Moment JS

Consider the code :
let now = moment();
console.log(now.format()); // 2019-11-25T20:23:50+02:00
console.log(now.toDate()); // 2019-11-25T18:23:50.916Z
This is the output on my local machine , and when I check the app on Heroku
it gives the same values , even though I changed the TZ like this :
heroku config:add TZ="Asia/Jerusalem"
How can I get a JavaScript Date (Not a String !) object of my localtime , meaning 2019-11-25T20:23:50 ?
Let's walk through your code example:
let now = moment();
You create a Moment object. You don't pass any parameters, so it is initialized using the current timestamp (as if you called Date.now()) and set to "local mode".
console.log(now.format()); // 2019-11-25T20:23:50+02:00
By calling format, you ask the Moment object to produce a String. Since it's in local mode, the offset that applies to that moment in time for the local time zone is emitted in the result, and the wall time shown in the result is adjusted for that offset. In this case, the local time is two hours ahead of UTC. You then pass that string to console.log, which emits it to the console.
console.log(now.toDate()); // 2019-11-25T18:23:50.916Z
By calling toDate, you ask the Moment object to create a Date object. The "mode" of the moment object is no longer relevant because Date objects don't track anything other than a timestamp. Thus, the timestamp within the Moment object becomes the timestamp for the resulting Date object. Since you derived the Moment object from the current time, the result is the same as if you just called new Date() to begin with.
You then pass the string to console.log - except one can't just log an object, so it first has to convert it to something so you can see it. Here's the interesting part: There is no spec for this behavior. Implementations of ECMAScript can do whatever they like in this regard. Some implementations, like in your example, will call .toISOString() and log the result. Since .toISOString() displays the result in UTC, the result of logging a Date object is also shown in UTC. But other implementations will call .toString() on the Date object and log that, the result being in local time. It's entirely possible some future implementation could show the result in some graphical or interactive output. The point being, you can't rely on the behavior of console.log(Date) to be consistent.
No amount of changing your time zone settings will change this result. The Date object is inherently UTC-based, your output is also UTC-based, and UTC is the same over the whole planet (by design).
If you want the time zone reflected in the string output, you must use a function that produces a string with respect to local time. As you showed, you'll get that with .format() on a Moment object in local mode. You can also get one from calling .toString() on a Date object (but the resulting string is not in the same ISO 8601 format).
i would try,
moment().local().toDate()
but if you are planning to save date into db it's good practice to save time in UTC format for easier global conversion.
If you want to work timezones you may require also moment timezone package - https://momentjs.com/timezone/docs/
npm install moment-timezone
Hope this helps :)

Angular/Javascript Luxon - Convert timestamp changing time to current user timezone

I got a timestamp from the database and I need to display its time in the user's timezone.
Ex: Brazil 16:42, France 21:42.
It's a chat, so the messages need to be displayed in each user's time zone.
I have luxon in the project, but I can not use any of the documentation that helps me in this case.
I have tried to use the methods in some ways
DateTime.local() and
DateTime.setZone(localZone)
localZone is a variable that receives the local area, for example: "Europe/Paris".
Thank you!
You can simply use luxon fromMillis to parse timestamp (assuming that it is in milliseconds) or fromSeconds if it is in seconds. You can also pass zone option to create luxon object using given timezone. The you can use toFormat() to display time in your desired format. You could have something like the following:
DateTime.fromMillis(timestamp, {zone: localZone}).toFormat('HH:mm')
If you need, you can also use setZone to change zone property, here a snippet using sample data:
const DateTime = luxon.DateTime;
let curTimestamp = 1562061791000;
let time = DateTime.fromMillis(curTimestamp)
console.log('Local time:', time.toFormat('HH:mm') );
console.log('Brazil time:', time.setZone('America/Sao_Paulo').toFormat('HH:mm') );
console.log('France time:', DateTime.fromMillis(curTimestamp, {zone: 'Europe/Paris'}).toFormat('HH:mm') );
<script src="https://cdn.jsdelivr.net/npm/luxon#1.16.0/build/global/luxon.js"></script>
If you want to use Luxon inside Angular view have a look to luxon-angular.

How to process data before set or get operation?

I am using primeNG calendar and I got a model called myDate and a dateformat. ngModel directive referencing to a Date property.
<p-calendar [(ngModel)]="myDate" dateFormat="dd/mm/yy"></p-calendar>
But problem is I want to store myDate value as Unix Timestamp. So I need to convert myDate to milliseconds before set and convert it to date object with dateformat before get operation. Is there any way to do this?
private myDate;
setMyDate(myNewDate){
this.myDate = convertDateToTimestamp(myNewDate)
}
getMyDate(){
return convertTimestampToDate(this.myDate)
}
You can call getTime() on this date object to get it in unix form. It comes out in milliseconds.
new Date("2013/09/05 15:34:00").getTime();
It may have decimal bits so wrapping it in Math.round would clean that.
Math.round(new Date("2013/09/05 15:34:00").getTime());
how to convert a string to a Unix timestamp in javascript?
You could use getters and setters to achieve this, which is actually very close to what you already have:
private _myDate;
set myDate(myNewDate){
this._myDate = convertDateToTimestamp(myNewDate)
}
get myDate(){
return convertTimestampToDate(this._myDate)
}

Creating and comparing dates inside CosmosDB stored procedures

There is limited guidance for CosmosDB stored procedures and their handling of new Date() and the comparison of dates.
The following code is a CosmosDB stored procedure to 'freeze' the writing of documents after a given time. The property currentDoc.FreezeDate is in ISO-8601 format, e.g. '2017-11-15T13:34:04Z'.
Note: this is an example of the situation I'm trying to understand. It is not production code.
function tryUpdate(newDoc) {
__.queryDocuments(
__.getSelfLink(),
{ /* query to fetch the document */ },
(error, results) => {
var currentDoc = results[0]; // doc from the database
// fail if the document is still locked
if (new Date(currentDoc.FreezeDate) < new Date()) {
getContext().getResponse().setBody({ success: false });
return;
}
// else update the document
/* snip */
}
);
}
My question is: within CosmosDB stored procedures, is new Date() affected by timezones, especially given that the database may be in a different region than the invoking code? Is the date comparison code here valid in all situations?
As far as I can see, CosmosDB is storing DateTime values without the corresponding Timezone, aka. not as DateTimeOffset. This means it should not matter where the code is executed, since it is always normalized to something like this:
"2014-09-15T23:14:25.7251173Z"
Javascript Date object are timestamps - they merely contain a number of milliseconds since the epoch. There is no timezone info in a Date object. Which calendar date (day, minutes, seconds) this timestamp represents is a matter of the interpretation (one of to...String methods).
(taken from Parse date without timezone javascript)
In other words, no matter where you are in the world, new Date() will always have the same value internally.
If you want to remove uncertainty in exchange for readability, I would recommend only storing the seconds or milliseconds since the epoch (Unix Time). This is also what is used internally by date (new Date().value - milliseconds). Incidentally, the internal cosmos document field _ts is also a timestamp in epoch format.
Be aware that the value of new Date() might by off the 'correct global time` by a couple of minutes - I don't know if Azure/Cosmos guarantees a certain deviation window.

Categories

Resources