107
votes

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?

19

19 Answers

179
votes

The constructor for a JavaScript Date doesn't know anything about Firestore 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.

28
votes

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
21
votes

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

{{ row.orderDate.toDate() | date: 'dd MMM hh:mm' }}

18
votes

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();
16
votes

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
5
votes
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

5
votes

This might help:

new Date(firebaseDate._seconds * 1000).toUTCString()
4
votes

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

new Date(firebase.firestore.Timestamp.now().seconds*1000).toLocaleDateString()
2
votes

This works for me.

new Date(firebaseDate.toDate())
1
votes

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)
0
votes

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

0
votes

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]

0
votes

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);
0
votes

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);
0
votes

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
votes

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.

0
votes

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)
0
votes

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.

0
votes

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();