Aggregate Group by Date with Daylight Saving Offset

北城以北 提交于 2019-12-05 04:40:02

问题


I'm trying to use mongo aggregation to group documents by the week of a timestamp on each document. All timestamps are stored in UTC time and I need to calculating the week using the clients time not UTC time.

I can provide and add the clients UTC offset as shown below but this doesn't always work due to daylight savings time. The offset is different depending on the date and therefore adjusting all the timestamps with the offset of the current date won't do.

Does anyone know of a way to group by week that consistently accounts for daylight savings time?

db.collection.aggregate([
    { $group: 
        { "_id": 
            { "$week": 
                { "$add": [ "$Timestamp", clientsUtcOffsetInMilliseconds ] } 
            } 
        },
        { "firstTimestamp": 
            { "$min": "$Timestamp"}
        }
    }   
]);

回答1:


The basic concept here is to make your query "aware" of when "daylight savings" both "starts" and "ends" for the given query period and simply supply this test to $cond in order to determine which "offset" to use:

db.collection.aggregate([
    { "$group": {
       "_id": {
           "$week": {
               "$add": [
                  "$Timestamp",
                  { "$cond": [
                      { "$and": [
                          { "$gte": [
                             { "$dayOfyear": "$Timestamp" },
                             daylightSavingsStartDay 
                          ]},
                          { "$lt": [ 
                             { "$dayOfYear": "$Timestamp" },
                             daylightSavingsEndDay
                          ]}
                      ]},
                      daylightSavingsOffset,
                      normalOffset
                  ]}
               ]
           }
       },
       "min": { "$min": "$Timestamp" }
    }}
])

So you can make that a little more complex when covering several years, but it still is the basic principle. In in the southern hemisphere you are always spanning a year so each condition would be a "range" of "start" to "end of year" and "begining of year" to "end". Therefore an $or with an inner $and within the "range" operators demonstrated.

If you have different values to apply, then detect when you "should" choose either and then apply using $cond.



来源:https://stackoverflow.com/questions/36465412/aggregate-group-by-date-with-daylight-saving-offset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!