Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
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 la diferencia entera entre startDate y endDate, medida 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 18 meses de diferencia devolverían una diferencia de 1 year en lugar de 1,5 years.

El inicio de week es Sunday a menos que se modifique por el parámetro startOfWeek. Se contará cualquier semana que comience entre el startDate y el endDate el día especificado. El conteo de semanas no está limitado por el calendario month o el calendario 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 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.

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 $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

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