代码之家  ›  专栏  ›  技术社区  ›  Yayo Arellano

如何在firestore和cloud函数中正确查询日期周期

  •  2
  • Yayo Arellano  · 技术社区  · 8 年前

    我收藏了下一个项目,其中一个属性是日期:

    id:   xxxxxx
    name: xxxx
    date: August 21, 2018 at 1:00:00 AM UTC+8 (timestamp)
    

    在firebase cloud函数中,我试图查询某个时段中的所有对象,该时段可以是天、周、年等。

    我想按当前服务器日期查询项目,所以我在Firebase Cloud函数中执行此操作:

    let auxDate = moment();
    dateStart = auxDate.startOf('day').toDate();
    dateEnd = auxDate.endOf('day').toDate();
    await admin.firestore().collection('items')
                .where("date", ">=", dateStart)
                .where('date', '<=', dateEnd).get();
    

    控制台中打印的dateStart和dateEnd值为:

    Date start: Tue Aug 21 2018 00:00:00 GMT+0000 (UTC)
    Date end:   Tue Aug 21 2018 23:59:59 GMT+0000 (UTC)
    

    查询返回0项。但是当我把物品的日期改成

    id:   xxxxxx
    name: xxxx
    date: August 21, 2018 at 8:00:00 AM UTC+8 (timestamp)
    

    所以现在我知道问题出在偏移量上了,但我该怎么解决呢?为什么firebase将所有日期保存为UTC+8?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Yayo Arellano    8 年前

    我找到了自己问题的答案。我会详细解释的。

    了解问题:
    首先要记住,我们是在云函数中执行这个查询的,所以我们不知道客户端时区。在Firestore中,所有日期都以UTC+00保存。所以如果我有一个项目像:

    id:   xxxxxx
    name: xxxx
    date: August 22, 2018 at 12:00:00 AM UTC+8 (timestamp)
    

    意思是这个日期等于 August 21, 2018 at 04:00:00 PM UTC+0

    因此,如果我想查询以下日期之间的所有日期:

    Date start: August 22, 2018 at 12:00:00 AM UTC+8 (timestamp) 
    Date end: August 22, 2018 at 11:59:59 PM UTC+8 (timestamp) 
    

    这意味着查询必须如下所示:

    Date start: August 21, 2018 at 04:00:00 AM UTC+0 (timestamp) 
    Date end: August 22, 2018 at 03:59:59 PM UTC+0 (timestamp) 
    

    所以问题是当我 let auxDate = moment() August 21, 2018 at 11:23:43 PM UTC+0 .

    所以从auxDate开始的日期变成:

    auxDate start: August 21, 2018 at 12:00:00 AM UTC+0 (timestamp) 
    auxDate end: August 21, 2018 at 11:59:59 PM UTC+0 (timestamp) 
    

    正如我们所看到的,这个查询没有填写我们必须查询的范围,很多项目将被删除。

    问题结论:
    如果我们不知道客户端的时区,则无法正确查询。


    现在我将客户端的当前时间传递给这个云函数,并计算开始和结束日期:

    const clientCurrentDateTime = "2018-08-22T11:23:15+08:00";
    let startDate = moment(clientCurrentDateTime).utcOffset(clientCurrentDateTime).startOf('day').toDate();
    let endDate = moment(clientCurrentDateTime).utcOffset(clientCurrentDateTime).endOf('day').toDate();
    

    推荐文章