198

I am trying to convert the below date to a javascript Date() object. When I get it back from the server, it is a Timestamp object,

Screenshot from Firebase Firestore console:

enter image description here

When I try the following on a list of objects returned from firestore:

  list.forEach(a => {
    var d = a.record.dateCreated;
    console.log(d, new Date(d), Date(d))
  })

I get this output: enter image description here

Clearly the Timestamps are all different, and are not all the same date of Sept 09, 2018 (which happens to be today). I'm also not sure why new Date(Timestamp) results in an invalid date. I'm a bit of a JS newbie, am I doing something wrong with the dates or timestamps?

blueether
  • 3,666
  • 4
  • 26
  • 32

26 Answers26

256

The constructor for a JavaScript's Date doesn't know anything about Firestore's Timestamp objects — it doesn't know what to do with them.

If you want to convert a Timestamp to a Date, use the toDate() method on the Timestamp.

Community
  • 1
  • 1
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 66
    @blueether or somebody else could post a working exemple ? Because I only get an error `...toDate() is not a function`. – Nitneq Oct 29 '20 at 12:57
  • 11
    toDate() is not a function – Muhammad Dec 07 '20 at 22:37
  • toDate is not a function, and when i m trying to convert time, it give some weird 3 months or 4 months old date – Chirag Joshi Jan 29 '21 at 15:54
  • @ChiragJoshi Without the ability to see and run your code, there's not much we can say. I suggest posting a new question with your specific details. – Doug Stevenson Jan 29 '21 at 15:56
  • @DougStevenson toDate() is giving error, i m using this var time=data.val().time; and gives me the date - 11-09-2020 11:43+0530 and where as my database date - 28-01-2021 03:48:07+0530 – Chirag Joshi Jan 29 '21 at 15:59
  • 1
    @ChiragJoshi You should post a new question that fully explains what you're doing and what doesn't work the way you expect. A comment on an answer is not a good place for this. – Doug Stevenson Jan 29 '21 at 16:16
  • Ypu should change type to any to avoid "is not a function" error. – LacOniC Jun 22 '21 at 03:52
  • @Nitneq see my answer https://stackoverflow.com/a/68248054/3073272 – GorvGoyl Jul 04 '21 at 19:29
  • toDate is nested under the writeTime object: `yourTimestamp.writeTime.toDate()` – 1252748 Feb 07 '22 at 23:09
  • 2
    Just trying to understand. Why should the OP post a new question instead of updating his current question? – Trevor Mar 09 '22 at 22:21
  • For anyone struggling with this, ensure you're actually dealing with the Timestamp object, not a JSON interpretation. If it's not a Timestamp object, you'll hit `toDate() is not a function` for obvious reasons. – bsplosion Apr 15 '22 at 02:06
  • 5
    Anyone who is getting the `toDate() is not a function` error and using the JavaScript SDK: For me I could simply convert the timestamp directly into a date using `new Date(timestamp)`. – benjiman May 13 '22 at 10:28
  • 4
    for anyone who is having `toDate() is not a function` error might be because you are using it on a JSON object. You can simply use the timestamp object received from firebase, or If you are not able to use it directly then To convert it back to timestamp object you can do this: `const timestamp = new firebase.firestore.Timestamp(jsonTimestamp.seconds, jsonTimestamp.nanoseconds)` now doing `timestamp.toDate()` will work – Rahul Kumar Mar 03 '23 at 04:52
  • @RahulKumar I like your answer . But what if I have Timestamp data and non timestamp data ? how to handle this situation ? Because I have original timestamp data. Then I will convert it to JSON and I will import again as JSON . so I have JSON object TimeStamp. How to handle these two things . I can't check the data type because they are same data type but different constructor class vs object . – ThanHtutZaw Apr 01 '23 at 14:03
  • wow @RahulKumar , I am very happy right now , Now firestore can understand my imported JSON timestamp . Will get error when seconds and nanosecods order change. here is my working code `timeStamp: new Timestamp(d.timeStamp?.seconds!, d.timeStamp?.nanoseconds!),` when code is nanseconds,seconds ( it will get time range error) – ThanHtutZaw Apr 01 '23 at 14:22
79

You can use toDate() function along with toDateString() to display the date part alone.

const date = dateCreated.toDate().toDateString()
//Example: Friday Nov 27 2017

Suppose you want only the time part then use the toLocaleTimeString()

const time = dateCreated.toDate().toLocaleTimeString('en-US')
//Example: 01:10:18 AM, the locale part 'en-US' is optional
Philippe Fanaro
  • 6,148
  • 6
  • 38
  • 76
M Thomas
  • 1,062
  • 1
  • 10
  • 12
  • 2
    This answer was what I was looking for. One additional tip for anyone wanting to convert the respective time (central time, in my case) to Eastern/New York time, you can do something like this:`const time = dateCreated.toDate().toLocaleTimeString('en-US', { timeZone: 'America/New_York' })` – SuttonY Jul 26 '22 at 19:37
  • 2
    This answer should be the accepted answer. – bilalmohib Aug 07 '22 at 00:32
37

You can use Timestamp.fromDate and .toDate for converting back and forth.

// Date to Timestamp
const t = firebase.firestore.Timestamp.fromDate(new Date());

// Timestamp to Date
const d = t.toDate();
Wajahath
  • 2,827
  • 2
  • 28
  • 37
29

How to convert Unix timestamp to JavaScript Date object.

var myDate = a.record.dateCreated;
new Date(myDate._seconds * 1000); // access the '_seconds' attribute within the timestamp object
Dilshan Liyanage
  • 4,440
  • 2
  • 31
  • 33
27

apart from other answers you can do it like this as well

    //date from firebase is represented as
    let time = {
      seconds: 1613748319,
      nanoseconds: 47688698687,
    }
    
    const fireBaseTime = new Date(
      time.seconds * 1000 + time.nanoseconds / 1000000,
    );
    const date = fireBaseTime.toDateString();
    const atTime = fireBaseTime.toLocaleTimeString();


    console.log(date, atTime);
Waleed Tariq
  • 825
  • 8
  • 19
24

Please use toDate() method and then convert it into the format using angular pipe like this -

   {{ row.orderDate.toDate() | date: 'dd MMM hh:mm' }}
christianbauer1
  • 467
  • 5
  • 16
Naman Sharma
  • 283
  • 3
  • 2
13

At last, I could get what I need. This returns date as 08/04/2020

new Date(firebase.firestore.Timestamp.now().seconds*1000).toLocaleDateString()
Nagibaba
  • 4,218
  • 1
  • 35
  • 43
12
const timeStampDate = record.createdAt;
const dateInMillis  = timeStampDate._seconds * 1000

var date = new Date(dateInMillis).toDateString() + ' at ' + new Date(dateInMillis).toLocaleTimeString()

OutPut Example: Sat 11 Jul 2020 at 21:21:10

Jorengarenar
  • 2,705
  • 5
  • 23
  • 60
Stephan Ngaha
  • 121
  • 1
  • 3
10

This might help:

new Date(firebaseDate._seconds * 1000).toUTCString()
Prottay
  • 385
  • 5
  • 9
9

A simple way is to convert firestore timestamp to epoch timestamp is by using toMillis() method on firestore timestamp.
For example: You have a firestore timestamp
created_on : Timestamp { _seconds: 1622885490, _nanoseconds: 374000000 }

let epochTimestamp = created_on.toMillis()
//epochTimestamp = 1621081015081
//Now this timestamp can be used as usual javascript timestamp which is easy to manipulate.
let date = new Date(epochTimestamp) //date = Sat May 15 2021 17:46:55 GMT+0530 (India Standard Time)
Dharman
  • 30,962
  • 25
  • 85
  • 135
6

The timestamp object you get from firestore has a toDate() method you can use.

list.forEach(a => {
  var d = a.record.dateCreated;
  console.log(d.toDate())
})

Here's a quote from firebase docs about the toDate() method

Convert a Timestamp to a JavaScript Date object. This conversion causes a loss of precision since Date objects only support millisecond precision.

Returns Date JavaScript Date object representing the same point in time as this Timestamp, with millisecond precision.

https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp#todate

Trevor
  • 13,085
  • 13
  • 76
  • 99
4

Lots of answer here, but as a rookie I found most of them confusing.

So for rookies like me, here is a simple explanation of how to convert a Firestore date/Timestamp to a Javascript Date() and why you need to.

Why convert?

Firestore stores Dates as a Timestamp object. This is not the same as a Javascript Date() object.

This was confusing to me because if you send a Date() object to Firestore, and then retrieve it, it will hand you back a Timestamp object. Like if you hand Firestore a dollar, it will hand you back 4 quarters. It is the same amount of money (or same date), but if you were expecting paper, and got metal, you would be confused.

How to convert

Luckily the Timestamp object has functions built into do give you a Javascript Date object: toDate

Note: Remember, toDate looks like the Javascript toLocaleDateString() or toDateString() but it is not. A JS Date() object and Firestore Timestamp object are not the same so don't make my rookie mistake of trying to use functions from one, on the other.

To convert a Firestore Timestamp into a Javascript date, just call .toDate() on the Timestamp.

//get the document from Firestore
let fireStoreTimestamp = doc.data().nameOfYourDateField;
let javascriptDate = fireStoreTimestamp.toDate();
Joshua Dance
  • 8,847
  • 4
  • 67
  • 72
3

This works for me.

new Date(firebaseDate.toDate())
Uddesh Jain
  • 1,064
  • 2
  • 15
  • 16
3

This works for me

let val = firebase.timestamp // as received from the database, the timestamp always comes in an object similar to this - {_nanoseconds: 488484, _seconds: 1635367}
    (new Date( (val.time._seconds + val.time._nanoseconds * 10 ** -9) * 1000)).toString().substring(17, 21)
2

You can use the dayjs library to convert firebase firestore timestamp seconds to your local time.

newDate =  dayjs.unix(date.seconds).$d;

It will take

date: { 
    seconds: 1639506600, 
    nanoseconds: 0 
}

and convert it to

Date Sat Nov 16 2019 00:00:00 GMT+0530 (India Standard Time)
2

To help those still looking around for an answer to convert Firestore Date to JS Date to display in the web app. Here goes an example using typescript...

import {
  Timestamp,
} from "firebase/firestore";

interface IStuff {
  createdAt: Timestamp;
}

const insertStuff = async (text: string) => {
    await addDoc(collection(db, "coolstuff"), {
      text,
      createdAt: serverTimestamp(),
    });
};

<p>{item.createdAt?.toDate().toDateString()}</p>

// OR

<p>{item.createdAt?.toDate().toLocaleTimeString()}</p>

Hendry Lim
  • 1,929
  • 2
  • 21
  • 45
2

Extending Waleed Tariq answer, to get a more readable string:

function formatDate(date) {
    const formatDate = new Date(
        date.seconds * 1000 + date.nanoseconds / 1000000
    );
    return formatDate.toLocaleTimeString('en-us', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
}

const timeStamp = {nanoseconds: 184000000, seconds: 1664826910};

console.log(formatDate(timeStamp))
Jairo Py
  • 615
  • 6
  • 12
1

to store timestamp into firestore:

import * as firebaseAdmin from "firebase-admin";

const created = firebaseAdmin.firestore.FieldValue.serverTimestamp();

// type
created: FirebaseFirestore.Timestamp | FirebaseFirestore.FieldValue | undefined;

To read back as a js Date object

const createDate = (created as FirebaseFirestore.Timestamp).toDate();

To read back as RFC3339 string

const createDate = (created as FirebaseFirestore.Timestamp).toDate().toISOString();
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
1

This is by far the most elegant, precise and easiest way to convert a firebase-timestamp to a date (no dependenceis etc. needed)

const date = new Intl.DateTimeFormat(
    'de-De', { 
           year: 'numeric', 
           month: 'numeric', 
           day: 'numeric', 
           hour: 'numeric', 
           minute: 'numeric' 
    }
).format(firebaseTimeStamp.toDate())

Here is a cheatsheet with all necesarry parameters

Andrew
  • 4,264
  • 1
  • 21
  • 65
0

I had the same problem. And i figured out like this:

const createdAt = firebase.firestore.Timestamp.fromDate(new Date());

// then using dayjs library you can display your date as you want.

const formatDate = dayjs.unix(createdAt.seconds).format('YYYY-MM-DD');

Output should look like e.g. 2020-08-04

Bastek
  • 43
  • 5
0

If you want don't want to lose the milliseconds you can do the following:

var myDate = a.record.dateCreated;
new Date((myDate.seconds + myDate.nanoseconds * 10 ** -9) * 1000);
tickietackie
  • 327
  • 4
  • 12
0

i work in angular.

i have an interface and a field date: Date.

the angular pipe date no work: order.date | date:'medium'

i change type of field date in interface

date: firebase.firestore.Timestamp

the angular pipe date work, but with function toDate()

order.date.toDate() | date:'medium'

0

It's very simple really. Use this simple epoch converter function which converts epoch seconds into Javascript date and time.

  function getUNIXTime(dt) {
    let unix = new Date(dt * 1000);
    return unix.toUTCString().slice(5, 16);   
}

Pass the timestamp.seconds into this function then slice it according to your needs to get a string of text with date and time.

arbob
  • 239
  • 2
  • 6
0

Normally using any type (i.e. loginDate:any) and toDate() worked without problem in my all projects. But in my last project it didn't. I saw seconds in Timestamp object is _seconds anymore (Firebase 8.6.8). This type of change may have affected it. I don't know but i had no time so i used an alternative solution. A custom pipe. It can be used as an alternative:

import { Pipe, PipeTransform } from '@angular/core';
import { formatDate } from '@angular/common';

@Pipe({
  name: 'timestamp'
})
export class TimestampPipe implements PipeTransform {

  transform(value: any, format?: string) {

    if (!value) { return ''; }
    if (!format) { format = 'dd MMM  yy'; }

    return formatDate(value._seconds * 1000, format, 'tr');
  }
}

and

{{ item.endDate | timestamp}}

P.S. Type is not important with this pipe. Worked with loginDate:any or loginDate:Date well.

LacOniC
  • 824
  • 12
  • 21
0

Web Firestore Timestamp:

function dateToFirestoreTimestamp(dateString = ''){
        var timestampDate = new Date();     // this will return current date-time
        if(dateString != ''){
            // this will return timestamp according to provided date-time
            dateString = dateString.replace(' ', 'T');
            timestampDate = new Date(dateString);
        } 
        timestampDate = firebase.firestore.Timestamp.fromDate(timestampDate);
        return timestampDate;
    }
Kamlesh
  • 5,233
  • 39
  • 50
0

this is the different thing between firestore timestamp and Javascript Date() object. if you want to use javascript Date() object from firestore timestamp, this is what I do:

const foo = new Date(firestoreTimestamp.toDate());

then you can use the javascript Date() object, as usual. here are some references:

https://www.w3schools.com/jsref/jsref_obj_date.asp

For example, we want to retrieve the date from the Date() object with string format:

const foo = new Date(firestoreTimestamp.toDate());
foo.toLocaleDateString();

etc.