Docs Menu
Docs Home
/ /

$dateDiff (operador de agregación)

$dateDiff

Nuevo en la versión 5.0.

Devuelve la diferencia entre dos fechas.

El $dateDiff La expresión tiene esta sintaxis:

{
$dateDiff: {
startDate: <Expression>,
endDate: <Expression>,
unit: <Expression>,
timezone: <tzExpression>,
startOfWeek: <String>
}
}

$dateDiff calcula la diferencia contando los límites superiores de los intervalos de tiempo cruzados startDate de a endDate dentro timezone de. La longitud de los intervalos de tiempo es igual a uno unit y ​​están alineados de forma que sus límites se encuentren en múltiplos enteros de unit a lo largo del eje del tiempo. Excluye las unidades parciales que no cruzan un límite. Esta expresión devuelve un entero en el unit especificado. Si endDate precede startDate a, devuelve un entero negativo.

Campo
Obligatorio/Opcional
Descripción

startDate

Requerido

El inicio del período de tiempo. El startDate puede ser cualquier expresión que se resuelve en una fecha, una marca de tiempo o un ObjectID.

endDate

Requerido

El final del período de tiempo.endDate puede ser cualquier expresión que se resuelva en una fecha, una marca de tiempo o un ID de objeto.

unit

Requerido

La medición de tiempo unit entre startDate endDatey. Es una expresión que se resuelve en una cadena:

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

timezone

Opcional

La zona horaria para realizar la operación. <tzExpression> debe ser una expresión válida que se resuelva en una cadena formateada como un identificador de zona horaria de Olsono una diferencia UTC. Si no timezone se proporciona, el resultado se muestra UTC en.

Formato
Ejemplos

Identificador de zona horaria de Olson

"America/New_York"
"Europe/London"
"GMT"

Desplazamiento UTC

+/-[hh]:[mm], e.g. "+04:45"
+/-[hh][mm], e.g. "-0530"
+/-[hh], e.g. "+03"

startOfWeek

Opcional

Se usa cuando la unidad week es. El valor predeterminado Sunday es. El startOfWeek parámetro es una expresión que se resuelve en una cadena que no distingue entre mayúsculas y minúsculas:

  • monday (o mon)

  • tuesday (o tue)

  • wednesday (o wed)

  • thursday (o thu)

  • friday (o fri)

  • saturday (o sat)

  • sunday (o sun)

Tip

Expresiones, tipos BSON.

La expresión $dateDiff devuelve la diferencia entera entre startDate y endDate medidos en el units especificado. Las duraciones se miden contando el número de veces que se sobrepasa un límite de unidad. Por ejemplo, dos fechas con una diferencia de 18 meses devolverían una diferencia de 1 year en lugar de 1.5 years.

El inicio de week es Sunday a menos que se modifique con el parámetro startOfWeek. Se contabilizará cualquier semana que comience entre startDate y endDate del día especificado. El conteo de semanas no está limitado por los calendarios month ni year.

Al utilizar un identificador de zona horaria de Olson en el campo <timezone>, MongoDB aplica el Desplazamiento del horario de verano, si corresponde para la zona horaria especificada.

Por ejemplo, considera una colección sales con el siguiente documento:

db.sales.insertOne(
{
"_id" : 1,
"item" : "abc",
"price" : 10,
"quantity" : 2,
"date" : ISODate("2014-01-01T08:15:39.736Z")
}
)

La siguiente agregación ilustra cómo MongoDB gestiona la diferencia horaria del identificador de zona horaria Olson. El ejemplo utiliza los operadores $hour y para devolver las partes correspondientes del $minute date campo:

db.sales.aggregate([
{
$project: {
"nycHour": {
$hour: { date: "$date", timezone: "-05:00" }
},
"nycMinute": {
$minute: { date: "$date", timezone: "-05:00" }
},
"gmtHour": {
$hour: { date: "$date", timezone: "GMT" }
},
"gmtMinute": {
$minute: { date: "$date", timezone: "GMT" } },
"nycOlsonHour": {
$hour: { date: "$date", timezone: "America/New_York" }
},
"nycOlsonMinute": {
$minute: { date: "$date", timezone: "America/New_York" }
}
}
}])

La operación devuelve el siguiente resultado:

{
"_id": 1,
"nycHour" : 5,
"nycMinute" : 24,
"gmtHour" : 10,
"gmtMinute" : 24,
"nycOlsonHour" : 6,
"nycOlsonMinute" : 24
}

El algoritmo calcula la diferencia de fechas utilizando el calendario gregoriano.

Se tienen en cuenta los años bisiestos y el horario de verano, pero no los segundos bisiestos.

La diferencia devuelta puede ser negativa.

Crear una colección de pedidos de clientes:

db.orders.insertMany(
[
{
custId: 456,
purchased: ISODate("2020-12-31"),
delivered: ISODate("2021-01-05")
},
{
custId: 457,
purchased: ISODate("2021-02-28"),
delivered: ISODate("2021-03-07")
},
{
custId: 458,
purchased: ISODate("2021-02-16"),
delivered: ISODate("2021-02-18")
}
]
)

El siguiente ejemplo:

  • Devuelve el número promedio de días para una entrega.

  • Utiliza dateDiff para calcular la diferencia entre la fecha purchased y la fecha delivered.

db.orders.aggregate(
[
{
$group:
{
_id: null,
averageTime:
{
$avg:
{
$dateDiff:
{
startDate: "$purchased",
endDate: "$delivered",
unit: "day"
}
}
}
}
},
{
$project:
{
_id: 0,
numDays:
{
$trunc:
[ "$averageTime", 1 ]
}
}
}
]
)

El acumulador$avgde la etapa$grouputiliza $dateDiff en cada documento para obtener el tiempo entre las fechas purchased y delivered. El valor resultante se devuelve como averageTime.

La parte decimal de averageTime se trunca ()$trunc $project en la etapa para producir un resultado como este:

{ "numDays" : 4.6 }

Crea esta colección con fechas de inicio y finalización de una suscripción.

db.subscriptions.insertMany(
[
{
custId: 456,
start: ISODate("2010-01-01"),
end: ISODate("2011-01-01")
},
{
custId: 457,
start: ISODate("2010-01-01"),
end: ISODate("2011-06-31")
},
{
custId: 458,
start: ISODate("2010-03-01"),
end: ISODate("2010-04-30")
}
]
)

La expresión $dateDiff devuelve una diferencia horaria expresada en el entero units. No hay fracciones en una unidad. Por ejemplo, al contar en years no hay medios años.

En este ejemplo, observe cómo al cambiar unit se modifica la precisión devuelta:

db.subscriptions.aggregate(
[
{
$project:
{
Start: "$start",
End: "$end",
years:
{
$dateDiff:
{
startDate: "$start",
endDate: "$end",
unit: "year"
}
},
months:
{
$dateDiff:
{
startDate: "$start",
endDate: "$end",
unit: "month"
}
},
days:
{
$dateDiff:
{
startDate: "$start",
endDate: "$end",
unit: "day"
}
},
_id: 0
}
}
]
)

Los resultados se resumen en esta tabla:

Inicio
End
Años
Meses
Días

2010-01-01

2011-01-01

1

12

365

2010-01-01

2011-07-01

1

18

546

2010-03-01

2010-04-30

0

1

60

El recuento solo aumenta cuando comienza un nuevo unit, por lo que 18 meses se informan como 1 año en la segunda fila y 60 días se informan como un mes en la tercera fila.

Crea una colección de meses:

db.months.insertMany(
[
{
month: "January",
start: ISODate("2021-01-01"),
end: ISODate("2021-01-31")
},
{
month: "February",
start: ISODate("2021-02-01"),
end: ISODate("2021-02-28")
},
{
month: "March",
start: ISODate("2021-03-01"),
end: ISODate("2021-03-31")
},
]
)

Puede cambiar el inicio de cada semana y contar la cantidad resultante de semanas en cada mes con el siguiente código:

db.months.aggregate(
[
{
$project:
{
wks_default:
{
$dateDiff:
{
startDate: "$start",
endDate: "$end",
unit: "week"
}
},
wks_monday:
{
$dateDiff:
{
startDate: "$start",
endDate: "$end",
unit: "week",
startOfWeek: "Monday"
}
},
wks_friday:
{
$dateDiff:
{
startDate: "$start",
endDate: "$end",
unit: "week",
startOfWeek: "fri"
}
},
_id: 0
}
}
]
)

Los resultados se resumen en esta tabla:

Mes
Domingo
Lunes
Viernes

Enero

5

4

4

Febrero

4

3

4

Marzo

4

4

4

De los resultados:

  • Cuando el startOfWeek es domingo, el 5.º week de enero de 2021 comienza el día 31.

  • Como el 31es domingo y está entre startDate y endDate, se agrega un week al recuento.

  • El recuento week se incrementa incluso cuando una semana del calendario finaliza después del endDate o en el siguiente período del calendario.

Volver

$dateAdd

En esta página