admin.Firebase.Timestamp stores time 7 hours behind - javascript

I'm trying to store a timestamp in Firestore from Firebase Functions. However, the incorrect time is being recorded in Firestore.
For instance, I want to store the UTC time:
August 14, 2021 21hr (9pm)
Note: this code is in my Firebase Function
const date = new Date(Date.UTC(
csvRow.startDateYear,
csvRow.startDateMonth,
csvRow.startDateDay,
csvRow.startDateHour,
csvRow.startDateMinute
))
console.log(date); // prints 2021-08-14T21:00:00.000Z (correct)
console.log('date.getTime():' + date.getTime()); // prints 1628974800000 (correct)
const timeStamp = admin.firestore.Timestamp.fromMillis(date.getTime());
console.log('timeStamp.toMillis():' + timeStamp.toMillis()); // prints 1628974800000 (correct)
write.startDate = timeStamp;
But when I actually look at the Firestore and see what's recorded, I get this, a timeStamp that's 7 hours behind:
I've also tried Timestamp.fromDate(date) but got the same result

Firebase Firestore TimeStamps break apart when using hours because they do not have timezones built into them. They are meant to represent a greater period of time, not for specific timezones (hour).
Try this function and see if it works properly:
var myTimestamp = firebase.firestore.Timestamp.fromDate(new Date());
If you are attempting this with Cloud Functions try the following:
admin.firestore.Timestamp.fromDate()
Detailed documentation:
https://firebase.google.com/docs/reference/node/firebase.firestore.Timestamp

Related

Cloud Firestore How to subtract hour from Timestamp

I am able to get the timestamp using this line in my index.js.
var now = admin.firestore.Timestamp.now();
I just want the timestamp that's 1 hour before now.
I've tried this and hasn't worked.
var old = now(now.seconds-1*60*60,milliseconds);
Also tried but it returns just the seconds instead of a timestamp
var old = admin.firestore.Timestamp.now().seconds - 1*60*60;
Any ideas on how to get the timestamp of an hour before?
Firestore's Timestamp class doesn't offer the ability to do "date math". You should do any date math using a native date type for your language, then convert that to a Timestamp when you're done.
Since you tagged this JavaScript, you could use a normal Date object to do the math:
const date = new Date(Date.now() - 60*60*1000)
The convert that to a Timestamp with Timestamp.fromDate():
const timestamp = admin.firestore.Timestamp.fromDate(date)

Use moment.js to change the timezone on a datetime stamp, without changing the time

I am migrating event data from an old SQL database to a new Mongo database, using NodeJS. However, whoever set up the SQL database created all of the dates for the events, made the times in PST/PDT, but the database believes they are in UTC time.
For Example:
A date from the SQL database may be: 23-APR-10 which MomentJS shows as: 2010-04-23T21:00:00Z when 21:00:00 is the PST time.
Is it possible to use pure JavaScript/MomentJS/NodeJS or a different npm module to change the timezone on the DateTime string without modifying the time (i.e. 2010-04-23T21:00:00Z would become 2010-04-23T21:00:00-8:00)?
PS. Even though the SQL database only shows DD-MMM-YY but returns a DateTime string when I query it.
Following the line of inquiry in the question comments, it seems your problem is that due to the timezone mishap, the timestamps stored in the db are stored without the timezone offset, and since your desired timezone is PST (UTC-8hours), the timestamps are 8 hours ahead, for instance, what should have been 2010-04-23T13:00:00Z has become 2010-04-23T21:00:00Z.
So what needs to be done here is that the utc offset for your desired timezone needs to be obtained and added to the date.
The offset in your case is known (-8 hours). However, we can fetch the correct offset of any desired timezone from the moment-timezone library.
const moment_timezone = require('moment-timezone');
//a sample timestamp you're getting from your db
const myDateObj = new Date("2010-04-23T21:00:00Z");
//timezone for PST as understood by moment-timezone
const myMomentTimezone = "America/Los_Angeles";
//offset for your timezone in milliseconds
const myTimezoneOffset = moment_timezone.tz(myMomentTimezone).utcOffset()*60000;
//perfom the correction
const getCorrectedDateObj = (givenDateObj) => new Date(givenDateObj.valueOf() + myTimezoneOffset);
console.log(getCorrectedDateObj(myDateObj));
You may notice that we are actually changing the timestamp, because the given timestamp and the requried timestamp are, due to the nature of the error, essentially different timestamps. Moment-timezone is only being used here to fetch the offset, it's not used to "convert" anything.
Anuj Pancholi's answer is correct, however; the old SQL database I'm using seems to have a lot of quirks, so I had to modify his answer to get my code working.
My Solution:
function getCorrectedDateObj(myDateObj){
const timezoneOffset = momentTimeZone.tz(timezone).utcOffset() * 60000;
const dt = new Date(myDateObj.valueOf() + timezoneOffset / 2);
dt.setHours(dt.getHours() + 12);
}

Get current timestamp in NodeJS in DD-MM-YY-23:59:42 format

I am running NodeJS 8 in AWS Lambda and want to timestamp and attach to an S3 the current day, month, year and current time when the function runs.
So if my function was running now, it would output 220619-183923 (Todays date and 6.39pm and 23 seconds in the evening.)
For something a little complex like this do I need something like MomentJS or can this be done in pure Javascript?
Eventually this will make up a S3 URL such as
https://s3.eu-west-2.amazonaws.com/mybucket.co.uk/BN-220619-183923.pdf
UPDATE
The webhook appears to have some date/time data albeit in slightly different formats that weren't outputted in the Lambda function, so these could prove useful here. Can ':' be used in a URL and could the UTC which I assume is in milliseconds be converted into my desired format?
createdDatetime=2019-06-22T18%3A20%3A42%2B00%3A00&
date=1561231242&
date_utc=1561227642&
Strangely, the date_utc value which is actually live real data. Seems to come out as 1970 here?! https://currentmillis.com/
You don't need moment. I have included a solution that is quite verbose, but is understandable. This could be shorted if needed.
Since you are using S3, you might also consider using the UTC versions of each date function (ie. .getMonth() becomes .getUTCMonth())
Adjust as needed:
createdDatetime= new Date(decodeURIComponent('2019-06-22T18%3A20%3A42%2B00%3A00'))
date=new Date(1561231242 * 1000);
date_utc=new Date(1561227642 * 1000);
console.log(createdDatetime, date, date_utc)
const theDate = createdDatetime;
const day = theDate.getUTCDate();
const month = theDate.getUTCMonth()+1;
const twoDigitMonth = month<10? "0" + month: month;
const twoDigitYear = theDate.getUTCFullYear().toString().substr(2)
const hours = theDate.getUTCHours();
const mins = theDate.getUTCMinutes();
const seconds = theDate.getUTCSeconds();
const formattedDate = `${day}${twoDigitMonth}${twoDigitYear}-${hours}${mins}${seconds}`;
console.log(formattedDate);
UPDATE based upon your update: The code here works as long as the input is a JavaScript Date object. The query parameters you provided can all be used to create the Date object.
You can definitely use MomentJS to achieve this. If you want to avoid using a large package, I use this utility function to get a readable format, see if it helps
https://gist.github.com/tstreamDOTh/b8b741853cc549f83e72572886f84479
What is the goal of creating this date string? If you just need it as a human-readable timestamp, running this would be enough:
new Date().toISOString()
That gives you the UTC time on the server. If you need the time to always be in a particular time zone, you can use moment.

How do I convert firebase.database.ServerValue.TIMESTAMP to its corresponding date or time now?

Here is my code, where I push a newsObj to the realtime database
addNewsObj(newsObj:News) {
this.newsListRef.push(newsObj).then((snap) => {
const key = snap.key;
console.log(key);
this.newsListRef.update(key, {news_timestamp_post_created: firebase.database.ServerValue.TIMESTAMP});
});
}
The outcome I want would be converting the long value I get from the db, something like this
news_timestamp_post_created:
1535716975480
To 59 mins ago or when it exceeds 24hrs, it displays it by days then months as time goes on. I wouldn't want something like 3000mins ago or 120days ago to be displayed on my app.
My problem here is that I dont know how to convert this 1535716975480 to readable terms
Any small tip would be a great help. Thank you!
EDIT:
I have tried doing this
let elapsed = news.news_timestamp_post_created;//1535716975480
console.log(new Date(elapsed));
which displayed 'Invalid date'
According to this SO link, the server timestamp is
"The doc says:
A placeholder value for auto-populating the current timestamp (time since the Unix epoch, in milliseconds) as determined by the Firebase servers"
I found out that,

Mongoose.js find yesterday's date in database

I want to find all the users created up until yesterday. This is my code to make the query string:
var today = new Date();
var a = today.getDate();
a--;
today.setDate(a);
var yesterday = today.toDateString();
and it returns something like: Sun Jan 17 2016... which IS yesterday's date, but the db stores the date in iso format like: "date" : ISODate("2016-01-13T13:23:08.419Z") so what I get is 2016-01-13T13:23:08.419Z. My problem now is that I can't use the yesterday variable to query the db for the users I need AND even if I could, I don't know how to find every registration not including the ones that took place today.
Any help? Thank you very much!
You are generating a date on the front end, and then pushing it back a day, which is totally fine for a lot of circumstances -
For this, since you are trying to find DB entries that occured, perhaps try querying the database with a timestamp ranged pulled from the ID's of each document in your database.
Here is some documentation on how to do that from mongoDB. https://docs.mongodb.org/v3.0/reference/method/ObjectId.getTimestamp/
I've also provided some additional resources that may help you figure out exactly what to query in regard to this method:
https://steveridout.github.io/mongo-object-time/
https://gist.github.com/tebemis/0e55aa0089e928f362d9
Some psuedo code:
1. Query documents in the database
2. Get a timestamp from the ID's of the documents in the database
3. Set a range of the timestamps
4. Compare returned timestamps vs a timestamp range variable (yesterdays date in this case)
5. Have the DB return only documents that are within the range
I hope this helps!
Try this, using Moment.js:
yesterday = moment().add(-1, 'days');
db.users.find({ "date": { "$lt": yesterday }});
Create a date object that represents the start of day today, use it to query your collection for documents where the date field is less than that variable, as in the following example
var start = new Date();
start.setHours(0,0,0,0);
db.users.find({ "date": { "$lt": start }});
This will look for users created up until end of day yesterday.
momentjs is a super handy utility for doing manipulations like this. Using the library, this can be achieved with the startOf() method on the moment's current date object, passing the string 'day' as arguments:
Local GMT:
var start = moment().startOf('day'); // set to 12:00 am today
db.users.find({ "date": { "$lt": start }});
For UTC:
var start = moment.utc().startOf('day');

Categories

Resources