• javascript与mongodb的日期时区问题


    默认情况下,js的日期生成是当地时区,但默认显示是按照GMT显示的:

    > var c = new Date('2017-10-31 06:00:00');
    > c
    2017-10-30T22:00:00.000Z
    

    但是日期对象中有时区信息,可以获取:

    > c.getTimezoneOffset()
    -480  // 以分钟为单位 晚于GMT则为正,早于则为负
    

    在获取关于日期/时间/星期等信息是按照当地时区的日期来获取的

    > c.getDate();
    31
    > c.getHours();
    6
    

    但是要注意的是,时间戳永远是按照GMT来统计的,即按照1970-01-01T00:00:00.000Z开始算的毫秒数

    > c.getTime();
    1509400800000
    > 1509400800000 / (60*60*1000*24) % 10000 % 1000 %100 %10 % 1 * 24
    22.000000000029104 
    

    也就是说,按照时间戳来算的话现在是晚上22点。
    不过一般情况下,直观上都是将时间戳转换成格式化的时间来显示。

    同样的mongodb的时间也是有时区信息的,也就是GMT时区,程序中的代码在写入数据库的时候会自动的转换成GMT保存,而在查询的时候也会像在js中那样显示。
    这种显示在绝大多数情况夏不会引起问题,只要在程序中保证使用的是本地时区,解释器和数据库驱动会自动去处理。
    极少遇到的一个困境是使用数据库本身的聚合操作进行统计的情况:
    假设我要使用mongodb的group聚合方法来统计每天创建的document的数量,如果按照如下处理的话,会出现问题:

    db.sales.aggregate(
       [
          {
            $group : {
               _id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
               totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
               averageQuantity: { $avg: "$quantity" },
               count: { $sum: 1 }
            }
          }
       ]
    )
    

    这里的聚合是按照数据库的时区来处理的,也就是会按照GMT时区来进行聚合,造成的结果是本地时区00:00-08:00的数据会后退一天,而我们期望的结果是按照当地时区的日期来统计数据。
    一个解决问题是在group之前对日期进行处理,先将日期加上时区偏差,然后再进行group:

    db.sales.aggregate(
       [
          {
            $group : {
               _id : { month: { $month: { "$add": [ "$date", 28800000] } }, day: { $dayOfMonth: { "$add": [ "$date", 28800000] } }, year: { $year: { "$add": [ "$date", 28800000] } } },
               totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } },
               averageQuantity: { $avg: "$quantity" },
               count: { $sum: 1 }
            }
          }
       ]
    )
    

    这样以后进行group之后的日期就是按照本地时区来统计的,其中28800000 = 8 * 60 * 60 * 1000,东8时区。

  • 相关阅读:
    Eclipse的安装
    为Eclipse绑定Tomcat
    CHIL-SQL-快速参考
    CHIL-SQL-FORMAT() 函数
    CHIL-SQL-NOW() 函数
    CHIL-SQL-ROUND() 函数
    CHIL-SQL-LEN() 函数
    CHIL-SQL-MID() 函数
    【PAT A1060】Are They Equal
    vector
  • 原文地址:https://www.cnblogs.com/zhangjpn/p/7775193.html
Copyright © 2020-2023  润新知