Firebase TIMESTAMP to date and Time - javascript
I am using firebase for my chat application. In chat object I am adding time stamp using Firebase.ServerValue.TIMESTAMP method.
I need to show the message received time in my chat application using this Time stamp .
if it's current time i need to show the time only.It's have days difference i need to show the date and time or only date.
I used the following code for convert the Firebase time stamp but i not getting the actual time.
var timestamp = '1452488445471';
var myDate = new Date(timestamp*1000);
var formatedTime=myDate.toJSON();
Please suggest the solution for this issue
A Timestamp is an object:
timestamp = {
nanoseconds: 0,
seconds: 1562524200
}
console.log(new Date(timestamp.seconds*1000))
Firebase.ServerValue.TIMESTAMP is not actual timestamp it is constant that will be replaced with actual value in server if you have it set into some variable.
mySessionRef.update({ startedAt: Firebase.ServerValue.TIMESTAMP });
mySessionRef.on('value', function(snapshot){ console.log(snapshot.val()) })
//{startedAt: 1452508763895}
if you want to get server time then you can use following code
fb.ref("/.info/serverTimeOffset").on('value', function(offset) {
var offsetVal = offset.val() || 0;
var serverTime = Date.now() + offsetVal;
});
inside Firebase Functions transform the timestamp like so:
timestampObj.toDate()
timestampObj.toMillis().toString()
documentation here https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp
In fact, it only work to me when used
firebase.database.ServerValue.TIMESTAMP
With one 'database' more on namespace.
For those looking for the Firebase Firestore equivalent. It's
firebase.firestore.FieldValue.serverTimestamp()
e.g.
firebase.firestore().collection("cities").add({
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
name: "Tokyo",
country: "Japan"
})
.then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
console.error("Error adding document: ", error);
});
Docs
I know the firebase give the timestamp in {seconds: '', and nanoseconds: ''}
for converting into date u have to only do:
take a firebase time in one var ex:- const date
and then date.toDate() => It returns the date.
For Firestore that is the new generation of database from Google, following code will simply help you through this problem.
var admin = require("firebase-admin");
var serviceAccount = require("../admin-sdk.json"); // auto-generated file from Google firebase.
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
var db = admin.firestore();
console.log(admin.firestore.Timestamp.now().toDate());
Solution for newer versions of Firebase (after Jan 2016)
The proper way to attach a timestamp to a database update is to attach a placeholder value in your request. In the example below Firebase will replace the createdAt property with a timestamp:
firebaseRef = firebase.database().ref();
firebaseRef.set({
foo: "bar",
createdAt: firebase.database.ServerValue.TIMESTAMP
});
According to the documentation, the value firebase.database.ServerValue.TIMESTAMP is: "A placeholder value for auto-populating the current timestamp (time since the Unix epoch, in milliseconds) by the Firebase Database servers."
Here is a safe method to convert a value from firebase Timestamp type to JS Date
in case the value is not Timestamp the method returns it as it is
Works for Angular 7/8/9
import firebase from 'firebase';
import Timestamp = firebase.firestore.Timestamp;
export function convertTimestampToDate(timestamp: Timestamp | any): Date | any {
return timestamp instanceof Timestamp
? new Timestamp(timestamp.seconds, timestamp.nanoseconds).toDate()
: timestamp;
}
Try this one,
var timestamp = firebase.firestore.FieldValue.serverTimestamp()
var timestamp2 = new Date(timestamp.toDate()).toUTCString()
Working with Firebase Firestone 18.0.1
(com.google.firebase.Timestamp)
val timestamp = (document.data["timestamp"] as Timestamp).toDate()
It is simple. Use that function to get server timestamp as milliseconds one time only:
var getServerTime = function( cb ) {
this.db.ref( '.info/serverTimeOffset' ).once( 'value', function( snap ) {
var offset = snap.val();
// Get server time by milliseconds
cb( new Date().getTime() + offset );
});
};
Now you can use it anywhere like that:
getServerTime( function( now ) {
console.log( now );
});
Why use this way?
According to latest Firebase documentation, you should convert your Firebase timestamp into milliseconds. So you can use estimatedServerTimeMs variable below:
var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", function(snap) {
var offset = snap.val();
var estimatedServerTimeMs = new Date().getTime() + offset;
});
While firebase.database.ServerValue.TIMESTAMP is much more accurate,
and preferable for most read/write operations, it can occasionally be
useful to estimate the client's clock skew with respect to the
Firebase Realtime Database's servers. You can attach a callback to the
location /.info/serverTimeOffset to obtain the value, in milliseconds,
that Firebase Realtime Database clients add to the local reported time
(epoch time in milliseconds) to estimate the server time. Note that
this offset's accuracy can be affected by networking latency, and so
is useful primarily for discovering large (> 1 second) discrepancies
in clock time.
https://firebase.google.com/docs/database/web/offline-capabilities
new Date(timestamp.toDate()).toUTCString()
import firebaseAPP from 'firebase/app';
public Date2firestoreTime(fromDate: Date) {
return firebaseAPP.firestore.Timestamp.fromDate(fromDate).toMillis()
}
public firestoreTime2Date(millisecDate: number) {
return firebaseAPP.firestore.Timestamp.fromMillis(millisecDate).toDate()
}
//usage:
let FSdatenow = this.Date2firestoreTime(new Date())
console.log('now to firestore TimeStamp', FSdatenow)
let JSdatenow = this.firestoreTime2Date(FSdatenow)
console.log('firestore TimeStamp to Date Obj', JSdatenow)
var date = new Date((1578316263249));//data[k].timestamp
console.log(date);
Iterating through this is the precise code that worked for me.
querySnapshot.docs.forEach((e) => {
var readableDate = e.data().date.toDate();
console.log(readableDate);
}
For me it works when the timeStamp is an integer rather than a string:
var timestamp = '1452488445471';
var myDate = new Date(parseInt(timestamp));
myDate.toDateString()
I converted to this format
let timestamp = '1452488445471';
let newDate = new Date(timestamp * 1000)
let Hours = newDate.getHours()
let Minutes = newDate.getMinutes()
const HourComplete = Hours + ':' + Minutes
let formatedTime = HourComplete
console.log(formatedTime)
let jsDate = new Date(date.seconds * 1000 + date.nanoseconds / 1000000);
You might have to specify the type to use .toDate() like this;
import { Timestamp } from "firebase/firestore";
...
(dateVariable as unknown as Timestamp).toDate()
This was .toDate() works as intended.
First Of All Firebase.ServerValue.TIMESTAMP is not working anymore for me.
So for adding timestamp you have to use Firebase.database.ServerValue.TIMESTAMP
And the timestamp is in long millisecond format.To convert millisecond to simple dateformat .
Ex- dd/MM/yy HH:mm:ss
You can use the following code in java:
To get the timestamp value in string from the firebase database
String x = dataSnapshot.getValue (String.class);
The data is in string now. You can convert the string to long
long milliSeconds= Long.parseLong(x);
Then create SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
Now convert your millisecond timestamp to ur sdf format
String dateAsString = sdf.format (milliSeconds);
After that you can parse it to ur Date variable
date = sdf.parse (dateAsString);
This code is work for me
<script src="https://www.gstatic.com/firebasejs/4.5.1/firebase.js"></script>
<script>
var config = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: ""
};
firebase.initializeApp(config);
var reff = firebase.database().ref('message');
reff.on('value',haveData, haveerr);
function haveData(datahave){
var existval= datahave.val();
var chabi=Object.keys(existval);
for(var d2=0;d2< chabi.length;d2++){
var r=chabi[d2];
var exitval=existval[r].Message;
var exitval1=existval[r].Name;
var exit=existval[r].Email;
var exitval2=existval[r].Subject;
var timestamp=existval[r].timestamp;
var sdate=new Date(timestamp);
var Year=sdate.getFullYear();
var month=sdate.getMonth()+1;
var day=sdate.getDate();
var hh=sdate.getHours();
var mm=sdate.getMinutes();
var ss=sdate.getSeconds();
}
}
function haveerr(e){
console.log(e);
}
</script>
Firebase.ServerValue.TIMESTAMP is the same as new Date().getTime().
Convert it:
var timestamp = '1452488445471';
var myDate = new Date(timestamp).getTime();
Related
How to use intervalToDuration function from date-fns
I tried using the intervalToDuration function from date-fns but I keep getting an error that says End Date is invalid. My code is as follows import { intervalToDuration} from "date-fns"; remaining() { const now = new Date(); const end = this.endDate; return intervalToDuration({ start: now, end: end, }); }, this.endDate is dynamically populated but for this question is equal to 2021-02-26T00:00:00.000Z
Since your endDate variable is coming from an API, it is being stored as a string, not a date. Calling intervalToDuration is expecting an interval object to be passed as the parameter. An interval consists of two Dates or Numbers (unix timestamp) To correct this, you must convert endDate to a date object, below is an untested example; const remaining = () => { const endDate = "2021-02-26T00:00:00.000Z"; const now = new Date(); const end = new Date(endDate); return intervalToDuration({ start: now, end: end }); }; const dur = remaining(); console.log("DURRATON ", JSON.stringify(dur)); // // Response == DURRATON {"years":0,"months":1,"days":8,"hours":15,"minutes":42,"seconds":0} // Notice : This does not handle timezones correctly. new Date() will create a datetime in the client timezone where it appears that your response from the API is in GMT timezone
Querying based on start date and end date in Firestore for created field which is timestamp [duplicate]
I need the help to query long collection with date range. See the below example document. I wanna query startTime field using date range.
Since I have the dueDate field stored as "timestamp" (and NOT as string or number) on Cloud Firestore, I did this to get the invoice documents with a due date on 2017: let start = new Date('2017-01-01'); let end = new Date('2018-01-01'); this.afs.collection('invoices', ref => ref .where('dueDate', '>', start) .where('dueDate', '<', end) ); NOTE: dueDate field was stored at firebase with a Date() object. e.g.: this.doc.dueDate = new Date('2017-12-25')
You could store the datetime object as Unix time (seconds since 1 January 1970). Then you can simple use the where select like this: collectionRef.where("startTime", ">=", "1506816000").where("startTime", "<=", "1507593600") Btw - to convert from datetime to Unix time in your app, you can use the excellent (now deprecated) library moment (if you are building something with js or node).
var startfulldate = admin.firestore.Timestamp.fromDate(new Date(1556062581000)); db.collection('mycollection') .where('start_time', '<=', startfulldate) .get() .then(snapshot => { var jsonvalue: any[] = []; snapshot.forEach(docs => { jsonvalue.push(docs.data()) }) res.send(jsonvalue); return; }).catch( error => { res.status(500).send(error) });
const event = new Date(); const expirationDate = admin.firestore.Timestamp.fromDate(event); const query = collectionRef.where('startTime', '<=', expirationDate)
As startTime stored as Timestamp, you can do this query range for more accururate (this good for both condition of long date range or same date range). const start = new Date('2021-01-01T00:00:00.000z'); const end = new Date('2021-03-01T23:59:59.000z'); db.collection('Data').where('startTime', '>=', start).where('startTime', '<=', end).get().then(data => { //pass your 'data' here }); I used this in my Node.js apps. Hopefully this useful.
For everyone recently using Firebase Firestore, there's a difference depending on your settings of your Firebase implementation (depending on the firebase version). Before, Firestore was saving Timestamp as a Date, however as described here in the docs the will be replaced soon by a Timestamp object. See the Timestamp docs here. You can force your implementation already by adding a setting in your code to force Firebase to use Timestamp objects instead of Date like this example: var firebaseApp = firebase.initializeApp({ apiKey: [APIKEY], authDomain: [FIREBASEAPPDOMAIN], projectId: [PROJECTID] }); var firestore = firebase.firestore(); var settings = { timestampsInSnapshots: true }; // force Timestamp instead of Date firestore.settings(settings);
The solution is to use Date.now(). Stop using timestamp service from Firebase, you need to work with the numerical value of the time in milliseconds like for example: 1514271367000, instead if Firestore uses 26/12/2017 1:56:07 GMT- 0500 (-05) will not work. An example of a query is: this.fsService.afs.collection('chats/4bY1ZpOr1TPq8bFQ3bjS/finance/123+finance/12345' , ref => ref.orderBy('hour').startAt(1514184967000).endAt(1514271367000)) .valueChanges().subscribe(data =>{ this.mensajes = data; })
Those who, like me, are using PHP to access Firestore, can do something like this: $startTime = new DateTime('2020-05-23 00:00:00'); $endTime = new DateTime('2020-06-23 23:59:59'); $start = new Google\Cloud\Core\Timestamp($startTime); $end = new Google\Cloud\Core\Timestamp($endTime); // fb is a Google\Cloud\Firestore\FirestoreClient object $this->query = $this->fb->collection('your_collection'); $aux = $this->query; $aux = $aux->where('startTime', '<', $end); $aux = $aux->where('startTime', '>', $start); return $aux->documents(); Enjoy.
Generic function to find documents in a collection by date range of specifics fields: public List<QueryDocumentSnapshot> findDocsByDateRange( String collection, String fieldStartDate, String fieldEndDate, Date startDate, Date endDate) { ApiFuture<QuerySnapshot> querySnapshot = fireStore() .collection(collection) .whereGreaterThanOrEqualTo(FieldPath.of(fieldStartDate), startDate) .whereLessThanOrEqualTo(FieldPath.of(fieldEndDate), endDate) .get(); return querySnapshot.get().getDocuments(); } Packages: import com.google.api.core.ApiFuture; import com.google.cloud.firestore.DocumentSnapshot; import com.google.cloud.firestore.FieldPath; import com.google.cloud.firestore.Firestore; import com.google.cloud.firestore.QueryDocumentSnapshot; import com.google.cloud.firestore.QuerySnapshot;
In a frontend application, this is how Firebase timestamps and dates can be used to query and store documents.
What worked for me was Format Date with Moment JS and split into Day, Month & Year const currentDate = moment().format("DD-MM-YYYY").split("-"); const currentDay = currentDate[0]; const currentMonth = currentDate[1]; const currentYear = currentDate[2]; const allDocuments = await collectionRef .doc(docId) .collection(*COLLECTION NAME*) .where( *DATE PARAMETER NAME*, ">=", new Date(`${currentYear}-${currentMonth}-${currentDay}`) ) .where( *DATE PARAMETER NAME*, "<", // ${parseInt(currentDay) + *Number of days you want in range*} new Date(`${currentYear}-${currentMonth}-${parseInt(currentDay) + 1}`) ) .get();
I think this will help you out, yourMethod() { var date = DateTime.now();// print("First Date > " + DateTime(date.year, date.month, 1).toString()); var datex = new DateTime(date.year, date.month + 1, 0); print("Last Date > " +datex);// // Firestore.instance .collection('biling') .where("driverId", isEqualTo: widget.uid) .where("date", isGreaterThanOrEqualTo: new DateTime(date.year, date.month, 1).toString())//1 .where("date", isLessThanOrEqualTo: datex.toString())//2 .orderBy('date', descending: true) .getDocuments() .then( (QuerySnapshot snapshot) => { snapshot.documents.forEach((f) { if (this.mounted) { setState(() { totalP += double.tryParse(f.data["price"]); }); } print("_price " + f.data["price"]); print("_duePaymntForCompay " + f.data["duePaymntForCompay"]); }), }, ); }
now you need to use these queries for filtering documents with conditions because .where() is not working for me db.collection("id").whereGreaterThan("field","value") .whereEqualTo("field","value") .whereLessThen("field","value")
Saving a String in MongoDB as a date saves wrong values
I am trying to save a string in MongoDB as a date but having hard times for storing the right values. In Mongoose schema data value is stored as Date, however, I pass the value to data as new Date("MM-dd-YYYY") but when I look up in the database the value is transformed to this format ISODate("YYYY-MM-dd-1T21:00:00Z") The format wouldn't bother me if the date would be the same but as you notice the value in the database is one day earlier then the value which I want to be. So instead of 2018-09-20 is 2018-08-19. My guess is that default UTC time is not the same or something like that but how can I set the correct UTC time? Edit: var mongoose = require('mongoose') var dateformat =require('moment'); //Schema var ReservationSchema = mongoose.Schema({ name : { type:String, required : true, }, numberOfGuests : { type : Number , required : true,} , email: { type : String, required:true, }, phone: { type : String, required:true, }, data:{ type:Date, require:true, }, timetables:{ type:String, require:true, }, furtherRequests: { type : String, } }); var reservvar = module.exports = mongoose.model('Rezervari', ReservationSchema ,'Rezervari'); module.exports.createReservation = function (query,callback){ //query.data = dateformat.utc(query.data).format("MM-DD-YYYY") reservvar.create(query,callback); } module.exports.getReservations = function (callback){ reservvar.find({},callback); } Index.js file : app.get('/api/reservations',function(req,res) { Rezervari.getReservations(function(err,reserv){ if(err){ throw err; } var changetime = reserv[1].data; console.log(reserv[1].data) changetime = dateformat.utc(changetime).format("MM-DD-YYYY") // this one returns the date in desired format but with wrong values as stored in db console.log(changetime) res.json(reserv); }); }); app.post('/api/createrezervare', function (req,res) { const reserv = req.body const name = reserv.name const numberofg = reserv.number const phone = reserv.phone const email = reserv.email const data = reserv.date const timetable = reserv.time const furtreq = reserv.frequests Rezervari.createReservation({name:name,numberOfGuests:numberofg,phone:phone,email:email,data:data,timetables:timetable,furtRequests:furtreq},function(err,reserv){ if(err){ throw err} res.json({status:true}) }) })
You are inserting a Javascript Date Object from Node.js, and that same Date is being inserted in MongoDB, it's being inserted correctly. I think you are confusing how dates are stored internally and how are they formatted when you print them. When you check the content of your data in MongoDB it's just shown in that particular format, an ISO date. If you take a close look at the date shown you can see a Z a the end, Z means "zero hour offset" also known as "Zulu time" (UTC). In Javascript when you create a Date object without setting the timezone, it's by default created in your system timezone. Also, Date objects are not stored with any format, nor in JS nor in MongoDB. In JS, dates are stored internally as time values (milliseconds since 1970-01-01). Supposing we are in Japan, JST time (UTC+9): const d = new Date("09-20-2018"); console.log(d.getTime()); // 1537369200000 console.log(d.toString()); // Thu Sep 20 2018 00:00:00 GMT+0900 (JST) console.log(d.toISOString()); // 2018-09-19T15:00:00.000Z First we are printing out the number of ms, after the Date including the timezone, and finally the ISO Date, almost same format that MongoDB uses to print dates in the Mongo shell (anyway, in UTC). So, new Date("09-20-2018") is going to store the milliseconds until 09-20-2018 00:00 in Japan Time. Then, if you insert that object in MongoDB, internally it will store the correct date (I don't know internal details of MongoDB, but maybe it's storing the milliseconds as well). If you check MongoDB you will see something like ISODate("2018-09-19T15:00:00Z").
Firebase getting server timestamp
I am trying to structure my firebase database as such. year/month/date/message e.g. 2017/08/26/message Therefore, I need to get the firebase server time to set the new message reference path. I have used Firebase.database.ServerValue.TIMESTAMP but it returns a placeholder that only gets converted to epoch time during inserting. Therefore my 'createdAt' field is correct. But I need a way to create my desired path structure. let epoch = Firebase.database.ServerValue.TIMESTAMP console.log(`epoch : ${epoch}`) // it returns an object let date = new Date(epoch) // date creation fail here console.log(`date : ${date}`) let messagesRef = db.ref(`messages/${date.getFullYear()}/${date.getMonth()}/${date.getDate()}`) let newMessage = { createdAt: epoch } messagesRef.push(newMessage)
There are ways but weird, easiest way I can think of is push the message, and then grab the message to get the timestamp you just pushed. Another way is get the key of a new pushRef messagesRef.push().key And then get timestamp from decoding the firebase key (since they are generated by timestamp) decode firebasekey #cartant state you can use server clock offset var offsetRef = firebase.database().ref(".info/serverTimeOffset"); offsetRef.on("value", function(snap) { var offset = snap.val(); var estimatedServerTimeMs = new Date().getTime() + offset; });
Convert UTC time to specific zone
I have the following data: var currentTime: 2013-07-11 15:55:36+00:00 var currentTimezone: Africa/Asmera I need a way to convert the currentTime in UTC to a new time based on currentTimezone. I've looked into Timezone.js and I'm having trouble implementing it (the directions on the site are a little ambiguous) The code for the function I'm intending on using is included. Thanks :) <script> $("#storeTime").click(function(){ storeCurrentTime(); }) $("#getTime").click(function(){ retrieveTime(); }) $("#storeTimezone").click(function(){ var yourTimezone = $('#timezone-select').find(":selected").text(); tz = yourTimezone.toString(); storeCurrentTimezone(tz); }) $("#convertTime").click(function(){ //get the most recent UTC time, clean it up var currentTime = $('#RetrievedTime').html(); currentTime = currentTime.split(": ")[1]; $('#convertedTime').html("Converted Time: " + currentTime); //get the saved timezone var currentTimezone = $('#storedTimezone').html(); }) </script>
You're going to need to know the timezone offset, so some sort of dictionary with strings to numbers. // assuming your dictionary says 3 hours is the difference just for example. var timezoneDiff = 3; Then you can just make a new time like this // Assuming you have the proper Date string format in your date field. var currentDate = new Date(currentTime); // Then just simply make a new date. var newDate = new Date(currentDate.getTime() + 60 * 1000 * timezoneDiff); Update I've written a javascript helper for this which you can find at: http://heuuuuth.com/projects/OlsonTZConverter.js I pulled the timezone data from the wikipedia page https://en.wikipedia.org/wiki/List_of_tz_database_time_zones Usage is as follows once included the script. var offset = OlsonTZConverter.GetUTCOffset("Africa/Asmera"); or if there is Daylight Savings in effect: var offset = OlsonTZConverter.GetUTCOffset("Africa/Asmera",true); These will throw if you pass an invalid timezone, but you can check if a timezone is valid with: var isValid = OlsonTZConverter.Contains("Africa/Asmera"); or just look at the entire dictionary with: var tzDict = OlsonTZConverter.ListAllTimezones(); Hope this maybe saves someone some time sometime :).