Docs Menu
Docs Home
/ /

$dateDiff (operador de expresión)

$dateDiff

Nuevo en la versión 5.0.

Devuelve la diferencia entre dos fechas.

La $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 desde startDate hasta endDate dentro del timezone. La duración de los intervalos de tiempo es igual a unit y están alineados de modo que sus límites ocurren en múltiplos enteros de unit a lo largo del eje temporal. Excluye las unidades parciales que no cruzan un límite. Esta expresión devuelve un entero en el unit especificado. Si endDate precede a startDate, retorna 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 una ObjectID.

endDate

Requerido

El final del periodo de tiempo. El endDate puede ser cualquier expresión que resuelva en una Fecha, un Sello de tiempo o un ObjectID.

unit

Requerido

La medición de tiempo unit entre el startDate y el endDate. Es una expresión que se resuelve en una string:

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

timezone

Opcional

La zona horaria para llevar a cabo la operación. <tzExpression> debe ser una expresión válida que se resuelva en una string formateada como un Identificador de zona horaria Olson o un Diferencia UTC. Si no se proporciona timezone, el resultado se muestra en UTC.

Formato
Ejemplos

Identificador de zona horaria 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 utiliza cuando la unidad es igual a week. Por defecto es Sunday. El parámetro startOfWeek es una expresión que se resuelve en una string insensible a mayúsculas:

  • monday (o mon)

  • tuesday (o tue)

  • wednesday (o wed)

  • thursday (o thu)

  • friday (o fri)

  • saturday (o sat)

  • sunday (o sun)

Tip

La expresión $dateDiff devuelve un número entero al comparar una parte específica de cada fecha. Para la unidad year, compara los valores del año: cualquier fecha en 2022 está a una year de distancia de cualquier fecha en 2023. Para la unidad week, compara los números de semana: cualquier fecha en la semana 5 está a una week de distancia de cualquier fecha en la semana 6.

El inicio de week es Sunday a menos que se modifique mediante el parámetro startOfWeek. $dateDiff cuenta cualquier semana que comience entre startDate y endDate en el día especificado. El conteo de semanas no está limitado por el calendario month ni por el calendario year.

Al utilizar un identificador de zona horaria Olson en el campo <timezone>, MongoDB aplica la Compensación DST 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 el ajuste de DST para el identificador de zona horaria Olson. El ejemplo usa los operadores $hour y $minute para devolver las partes correspondientes del campo date:

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 intercalares.

La diferencia devuelta puede ser negativa.

Crea 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 $avg en la etapa $group utiliza $dateDiff en cada documento para obtener el tiempo transcurrido entre las fechas purchased y delivered. El valor resultante se devuelve como averageTime.

La parte decimal del averageTime se trunca ($trunc) en la etapa $project para producir una salida como esta:

{ "numDays" : 4.6 }

Cree esta colección con fechas de inicio y finalización para 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 de tiempo expresada en units enteros. No hay partes fraccionarias de una unidad. Por ejemplo, al contar en years no hay medios años.

En este ejemplo, observe cómo cambiar el unit cambia 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 la siguiente 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

En la segunda fila, 2010-01-01 y 2011-07-01 están en años diferentes (2010 y 2011), por lo que $dateDiff devuelve 1 year. En la tercera fila, 2010-03-01 (marzo) y 2010-04-30 (abril) difieren en un mes, por lo que $dateDiff devuelve 1 month.

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 la siguiente 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.

  • Debido a que el día 31 es un domingo y se encuentra entre startDate y endDate, se suma un week a la cuenta.

  • El contador week se incrementa incluso cuando una semana calendario termina después de endDate o en el siguiente período calendario.

Volver

$dateAdd

En esta página