Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ / /

$dateDiff (agregação)

Nesta página

  • Definição
  • Comportamento
  • Exemplos
$dateDiff

Novidades na versão 5.0.

Retorna a diferença entre duas datas.

A expressão $dateDiff tem esta sintaxe:

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

Subtrai startDate de endDate. Retorna um número inteiro no unit especificado.

Campo
Obrigatório/Opcional
Descrição
startDate
Obrigatório
O início do período. O startDate pode ser qualquer expressão que resolva para uma Data, um carimbo de Data/hora ou um ObjectID.
endDate
Obrigatório
O fim do período. O endDate pode ser qualquer expressão que resolva para uma Data, um Timestamp ou um ObjectID.
unit
Obrigatório

A medição de tempo unit entre startDate e endDate. É uma expressão que se resolve para uma string:

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

timezone
Opcional

O fuso horário para realizar a operação. <tzExpression> deve ser uma expressão válida que resolva para uma string formatada como um Identificador de fuso horário Olson ou um Deslocamento UTC. Se nenhum timezone for fornecido, o resultado será exibido em UTC.

Formatar
Exemplos
Identificador de fuso horário Olson
"America/New_York"
"Europe/London"
"GMT"
UTC Offset
+/-[hh]:[mm], e.g. "+04:45"
+/-[hh][mm], e.g. "-0530"
+/-[hh], e.g. "+03"
startOfWeek
Opcional

Usado quando a unidade é igual a week. O padrão é Sunday. O parâmetro startOfWeek é uma expressão que resolve uma string que não diferencia maiúsculas de minúsculas:

  • monday (ou mon)

  • tuesday (ou tue)

  • wednesday (ou wed)

  • thursday (ou thu)

  • friday (ou fri)

  • saturday (ou sat)

  • sunday (ou sun)

Dica

Veja também:

A expressão $dateDiff retorna a diferença de número inteiro entre startDate e endDate medido no units especificado. As durações são medidas contando o número de vezes que um limite unitário é passado. Por exemplo, duas datas com 18 meses de diferença retornariam uma diferença de 1 year em vez de 1,5 years.

O início do week é Sunday, a menos que seja modificado pelo parâmetro startOfWeek. Qualquer semana que comece entre startDate e endDate no dia especificado será contada. A contagem de semanas não é limitada pelo calendário month ou pelo calendário year.

Ao usar um Identificador de Fuso Horário Olson no campo <timezone>, o MongoDB aplica o deslocamento de horáriode verão , se aplicável, para o fuso horário especificado.

Por exemplo, considere uma collection sales com o seguinte documento:

{
"_id" : 1,
"item" : "abc",
"price" : 20,
"quantity" : 5,
"date" : ISODate("2017-05-20T10:24:51.303Z")
}

A seguinte agregação ilustra como o MongoDB lida com o deslocamento DST para o Identificador de fuso horário Olson. O exemplo utiliza os operadores $hour e $minute para retornar as partes correspondentes do 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" }
}
}
}])

A operação retorna o seguinte resultado:

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

O algoritmo calcula a diferença de data usando o calendário gregoriano.

Os anos bissextos e o horário de verão são contabilizados, mas não os segundos bissextos.

A diferença retornada pode ser negativa.

Crie uma coleção 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")
}
]
)

O seguinte exemplo:

  • Retorna o número médio de dias para uma entrega.

  • Utiliza dateDiff para calcular a diferença entre a data de purchased e a data de delivered.

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

O acumulador de $avg na etapa $group utiliza $dateDiff em cada documento para obter o tempo entre as datas de purchased e delivered. O valor resultante é retornado como averageTime.

A parte decimal do averageTime é truncada($trunc) no estágio $project para produzir uma saída como esta:

{ "numDays" : 4.6 }

Crie esta coleção com datas de início e fim para uma assinatura.

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")
}
]
)

A expressão $dateDiff retorna uma diferença de tempo expressa no número inteiro units. Não há partes fracionárias de uma unidade. Por exemplo, ao contar em years não há meios anos.

Neste exemplo, observe como alterar o unit altera a precisão retornada:

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
}
}
]
)

Os resultados são resumidos nesta tabela:

Iniciar
End
Anos
Meses
Dias
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

A contagem só aumenta quando um novo unit começa, portanto, 18 meses são relatados como 1 ano na segunda linha e 60 dias são relatados como um mês na terceira linha.

Crie uma coleção 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")
},
]
)

Você pode alterar o início de cada semana e contar o número resultante de semanas em cada mês com o seguinte 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
}
}
]
)

Os resultados são resumidos nesta tabela:

Mês
Domingo
Segunda-feira
Sexta-feira
Janeiro
5
4
4
Fevereiro
4
3
4
Março
4
4
4

Dos resultados:

  • Quando startOfWeek for domingo, dia 5 week de janeiro de 2021 começa no dia 31.

  • Como o 31º é um domingo e está entre startDate e endDate, um week é adicionado à contagem.

  • A contagem de week é incrementada mesmo quando uma semana de calendário termina após endDate ou no próximo período de calendário.

Voltar

$dateAdd