Cómo agregar por año-mes-día en una zona horaria diferente

Tengo un MongoDB que almacena los objetos de fecha en UTC. Bueno, quiero realizar la agregación por año, mes y día en una zona horaria diferente (CET).

haciendo esto, funciona bien para UTC:

BasicDBObject group_id = new BasicDBObject("_id", new BasicDBObject("year", new BasicDBObject("$year", "$tDate")). append("month", new BasicDBObject("$month", "$tDate")). append("day", new BasicDBObject("$dayOfMonth", "$tDate")). append("customer", "$customer")); BasicDBObject groupFields = group_id. append("eventCnt", new BasicDBObject("$sum", "$eventCnt")); BasicDBObject group = new BasicDBObject("$group", groupFields); 

o, si usa la línea de comando (no probada, solo probé la versión de Java):

 { $group: { _id: { "year": { "$year", "$tDate" }, "month": { "$month", "$tDate" }, "day": { "$dayOfMonth", "$tDate" }, "customer": "$customer" }, "eventCount": { "$sum": "$eventCount" } } } 

¿Cómo convierto estas fechas en CET dentro del marco de agregación?

Por ejemplo, ‘2013-09-16 23:45:00 UTC’ es ‘2013-09-17 00:45:00 CET’, este es un día diferente.

No soy un experto en CET y su relación con UTC, pero el siguiente código (para el shell) debe hacer una conversión adecuada (agregando una hora) a un tipo de fecha MongoDB:

 db.dates.aggregate( {$project: {"tDate":{$add: ["$tDate", 60*60*1000]}, "eventCount":1, "customer":1}} ) 

Si ejecuta ese comando de proyecto antes del rest de su canalización, los resultados deberían estar en CET.

Después de buscar durante horas, esta es la solución que funcionó para mí. También es muy simple. Simplemente convierta la zona horaria restando el desplazamiento de la zona horaria en milisegundos.

25200000 = Desplazamiento de 7 horas // 420 min * 60 seg * 1000 mili

 $group: { _id = { year: { $year : [{ $subtract: [ "$timestamp", 25200000 ]}] }, month: { $month : [{ $subtract: [ "$timestamp", 25200000 ]}] }, day: { $dayOfMonth : [{ $subtract: [ "$timestamp", 25200000 ]}] } }, count = { $sum : 1 } }; 

Utilice, por ejemplo, moment.js para desviar el desplazamiento de la zona horaria actual para CET, pero de esta manera obtendrá las compensaciones de verano e invierno.

 var offsetCETmillisec = moment.tz.zone('Europe/Berlin').offset(moment())* 60 * 1000; $group: { _id: { 'year': {'$year': [{ $subtract: [ '$createdAt', offsetCETmillisec ]}] }, 'month': {'$month': [{ $subtract: [ '$createdAt', offsetCETmillisec ]}] }, 'day': {'$dayOfMonth': [{ $subtract: [ '$createdAt', offsetCETmillisec ]}] } }, count: {$sum: 1} } } 

Puede proporcionar la timezone a los operadores de fecha que comienzan en 3.6.

Reemplace la zona horaria con su zona horaria.

 { "$group":{ "_id":{ "year":{"$year":{"date":"$tDate","timezone":"America/Chicago"}}, "month":{"$month":{"date":"$tDate","timezone":"America/Chicago"}}, "dayOfMonth":{"$dayOfMonth":{"date":"$tDate","timezone":"America/Chicago"}} }, "count":{"$sum":1} } } 

La documentación de MongoDB sugiere que guarde el desplazamiento de la zona horaria junto con la marca de tiempo:

 var now = new Date(); db.data.save( { date: now, offset: now.getTimezoneOffset() } ); 

Por supuesto, esta no es la solución ideal, pero funciona, hasta que tengamos en la línea de agregación de MongoDb una función $ utcOffset adecuada.

  
    Intereting Posts