【问题标题】:How do I convert a Firestore date/Timestamp to a JS Date()?如何将 Firestore 日期/时间戳转换为 JS Date()?
【发布时间】:2020-08-10 00:36:16
【问题描述】:

我正在尝试将以下日期转换为 javascript Date() 对象。当我从服务器取回它时,它是一个 Timestamp 对象,

Firebase Firestore 控制台的屏幕截图:

当我在从 firestore 返回的对象列表上尝试以下操作时:

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

我得到这个输出:

显然,时间戳都不同,并且并非都是 2018 年 9 月 9 日(恰好是今天)的同一日期。我也不确定为什么new Date(Timestamp) 会导致invalid date。我是一个 JS 新手,我在日期或时间戳方面做错了吗?

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    这是迄今为止最优雅、精确和最简单的将 firebase-timestamp 转换为日期的方法(不需要依赖等)

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

    这是一个cheatsheet,包含所有必要的参数

    【讨论】:

      【解决方案2】:

      请使用toDate() 方法,然后像这样使用角管将其转换为格式 -

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

      【讨论】:

        【解决方案3】:

        一种简单的方法是将 Firestore 时间戳转换为纪元时间戳,即在 firestore 时间戳上使用 toMillis() 方法。
        例如: 您有一个 Firestore 时间戳
        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)
        

        【讨论】:

          【解决方案4】:

          Web Firestore 时间戳:

          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;
              }
          

          【讨论】:

            【解决方案5】:

            将时间戳存储到 Firestore:

            import * as firebaseAdmin from "firebase-admin";
            
            const created = firebaseAdmin.firestore.FieldValue.serverTimestamp();
            
            // type
            created: FirebaseFirestore.Timestamp | FirebaseFirestore.FieldValue | undefined;
            

            js Date 对象的形式回读

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

            回读为RFC3339 字符串

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

            【讨论】:

              【解决方案6】:

              通常使用任何类型(即 loginDate:any)和 toDate() 在我的所有项目中都没有问题。但在我的上一个项目中没有。我在 Timestamp 对象中看到 seconds 不再是 _seconds (Firebase 8.6.8)。这种类型的变化可能已经影响了它。我不知道,但我没有时间,所以我使用了替代解决方案。自定义管道。它可以用作替代品:

              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');
                }
              }
              

              {{ item.endDate | timestamp}}
              

              附:类型对于此管道并不重要。使用 loginDate:any 或 loginDate:Date 很好。

              【讨论】:

                【解决方案7】:

                您可以使用 dayjs 库将 Firebase Firestore 时间戳秒数转换为您的本地时间。

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

                需要

                date: { 
                    seconds: 1639506600, 
                    nanoseconds: 0 
                }
                

                并将其转换为

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

                【讨论】:

                  【解决方案8】:

                  真的很简单。使用这个简单的纪元转换器函数,将纪元秒数转换为 Javascript 日期和时间。

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

                  timestamp.seconds 传递到此函数中,然后根据您的需要对其进行切片以获得带有日期和时间的文本字符串。

                  【讨论】:

                    【解决方案9】:

                    我在角度工作。

                    我有一个界面和一个字段日期:日期。

                    角管日期无效:order.date |日期:'中'

                    我在界面中更改字段日期的类型

                    date: firebase.firestore.Timestamp
                    

                    角度管道日期工作,但使用函数 toDate()

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

                    【讨论】:

                    • 你能改进一下你的问题吗?
                    【解决方案10】:

                    除了其他答案,你也可以这样做

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

                    【讨论】:

                      【解决方案11】:

                      这可能会有所帮助:

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

                      【讨论】:

                        【解决方案12】:

                        这对我有用

                        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)
                        

                        【讨论】:

                          【解决方案13】:

                          如果您不想丢失毫秒,您可以执行以下操作:

                          var myDate = a.record.dateCreated;
                          new Date((myDate.seconds + myDate.nanoseconds * 10 ** -9) * 1000);
                          

                          【讨论】:

                            【解决方案14】:

                            您从 firestore 获得的时间戳对象有一个您可以使用的 toDate() 方法。

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

                            这是 firebase 文档中关于 toDate() 方法的引用

                            将时间戳转换为 JavaScript 日期对象。这种转换 导致精度损失,因为 Date 对象仅支持毫秒 精度。

                            返回 Date 表示同一点的 JavaScript Date 对象 时间作为这个时间戳,以毫秒为精度。

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

                            【讨论】:

                              【解决方案15】:

                              我遇到了同样的问题。我是这样想的:

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

                              输出应该看起来像例如2020-08-04

                              【讨论】:

                                【解决方案16】:
                                const timeStampDate = record.createdAt;
                                const dateInMillis  = timeStampDate._seconds * 1000
                                
                                var date = new Date(dateInMillis).toDateString() + ' at ' + new Date(dateInMillis).toLocaleTimeString()
                                

                                输出示例:Sat 11 Jul 2020 at 21:21:10

                                【讨论】:

                                  【解决方案17】:

                                  这对我有用。

                                  new Date(firebaseDate.toDate())
                                  

                                  【讨论】:

                                    【解决方案18】:

                                    您可以使用 toDate() 函数和 toDateString() 来单独显示日期部分。

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

                                    假设您只需要时间部分,然后使用 toLocaleTimeString()

                                    const time = dateCreated.toDate().toLocaleTimeString('en-US')
                                    //Example: 01:10:18 AM, the locale part 'en-US' is optional
                                    

                                    【讨论】:

                                      【解决方案19】:

                                      您可以使用Timestamp.fromDate.toDate 来回转换。

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

                                      【讨论】:

                                        【解决方案20】:

                                        终于,我可以得到我需要的东西了。这将返回日期为08/04/2020

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

                                        【讨论】:

                                          【解决方案21】:

                                          如何将 Unix 时间戳转换为 JavaScript Date 对象。

                                          var myDate = a.record.dateCreated;
                                          new Date(myDate._seconds * 1000); // access the '_seconds' attribute within the timestamp object
                                          

                                          【讨论】:

                                            【解决方案22】:

                                            JavaScript Date 的构造函数对 Firestore Timestamp 对象一无所知 - 它不知道如何处理它们。

                                            如果要将时间戳转换为日期,请对时间戳使用 toDate() 方法。

                                            【讨论】:

                                            • 感谢您的快速回答,这正是我所需要的
                                            • @blueether 或其他人可以发布一个工作示例?因为我只收到一个错误...toDate() is not a function
                                            • toDate() 不是函数
                                            • toDate 不是函数,当我尝试转换时间时,它会给出一些奇怪的 3 个月或 4 个月大的日期
                                            • @ChiragJoshi 您应该发布一个新问题,充分说明您在做什么以及哪些不符合您的预期。对答案发表评论不是一个好地方。
                                            猜你喜欢
                                            • 2021-12-10
                                            • 2019-09-13
                                            • 2019-05-10
                                            • 2018-12-09
                                            • 2020-02-23
                                            • 1970-01-01
                                            • 2019-10-09
                                            • 1970-01-01
                                            相关资源
                                            最近更新 更多