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

$dateAdd (agregação)

Nesta página

  • Definição
  • Comportamento
  • Exemplos
$dateAdd

Novidades na versão 5.0.

Incrementa um objeto Date() em um número especificado de unidades de tempo.

A expressão $dateAdd tem a seguinte sintaxe:

{
$dateAdd: {
startDate: <Expression>,
unit: <Expression>,
amount: <Expression>,
timezone: <tzExpression>
}
}

Retorna um Date(). O startDate pode ser qualquer expressão que resolva o tipo Date, Timestamp ou ObjectId. Não importa qual tipo de dados é usado como entrada, o valor retornado será um objeto Date() .

Campo
Obrigatório/Opcional
Descrição
startDate
Obrigatório
A data inicial, em UTC, para a operação de adição. O startDate pode ser qualquer expressão que resolva para uma Data, um Timestamp ou um ObjectID.
unit
Obrigatório

O unit usado para medir o amount de tempo adicionado ao startDate. O unit é uma expressão que se resolve em uma das seguintes strings:

  • year

  • quarter

  • week

  • month

  • day

  • hour

  • minute

  • second

  • millisecond

amount
Obrigatório
O número de units adicionado ao startDate. O amount é uma expressão que resolve para um inteiro ou longo. O amount também pode ser resolvido como um decimal integral ou double se esse valor puder ser convertido em um valor longo sem perda de precisão.
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 UTC Offset. 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"

Para mais informações sobre expressões e tipos, consulte Operadores de Expressão e Tipos de JSON.

O MongoDB segue o uso predominante do banco de dados e trabalha com o tempo em UTC. A expressão dateAdd sempre pega um startDate em UTC e retorna um resultado em UTC. Se o timezone for especificado, o cálculo será feito utilizando o timezone especificado. O fuso horário é especialmente importante quando um cálculo envolve Horário de Verão (DST).

Se unit for month ou maior, a operação será ajustada para contabilizar o último dia do mês. Adicionar um month no último dia de outubro, por exemplo, demonstra o ajuste de "último dia do mês".

{
$dateAdd:
{
startDate: ISODate("2020-10-31T12:10:05Z"),
unit: "month",
amount: 1
}
}

Observe que a data retornada, ISODate("2020-11-30T12:10:05Z"), é 30 e não 31, pois novembro tem menos dias do que outubro.

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
}

Considere uma coleção de pedidos de clientes com estes documentos:

db.shipping.insertMany(
[
{ custId: 456, purchaseDate: ISODate("2020-12-31") },
{ custId: 457, purchaseDate: ISODate("2021-02-28") },
{ custId: 458, purchaseDate: ISODate("2021-02-26") }
]
)

O tempo normal de envio é de 3 dias. Você pode usar $dateAdd em um aggregation pipeline para definir expectedDeliveryDate 3 dias no futuro.

db.shipping.aggregate(
[
{
$project:
{
expectedDeliveryDate:
{
$dateAdd:
{
startDate: "$purchaseDate",
unit: "day",
amount: 3
}
}
}
},
{
$merge: "shipping"
}
]
)

Após adicionar 3 dias ao purchaseDate com $dateAdd no estágio $project, o estágio $merge atualiza os documentos originais com o expectedDeliveryDate.

Os documentos resultantes têm a seguinte aparência:

{
"_id" : ObjectId("603dd4b2044b995ad331c0b2"),
"custId" : 456,
"purchaseDate" : ISODate("2020-12-31T00:00:00Z"),
"expectedDeliveryDate" : ISODate("2021-01-03T00:00:00Z")
}
{
"_id" : ObjectId("603dd4b2044b995ad331c0b3"),
"custId" : 457,
"purchaseDate" : ISODate("2021-02-28T00:00:00Z"),
"expectedDeliveryDate" : ISODate("2021-03-03T00:00:00Z")
}
{
"_id" : ObjectId("603dd4b2044b995ad331c0b4"),
"custId" : 458,
"purchaseDate" : ISODate("2021-02-26T00:00:00Z"),
"expectedDeliveryDate" : ISODate("2021-03-01T00:00:00Z")
}

Atualize a coleção shipping do último exemplo com este código para adicionar datas de entrega aos documentos:

db.shipping.updateOne(
{ custId: 456 },
{ $set: { deliveryDate: ISODate( "2021-01-10" ) } }
)
db.shipping.updateOne(
{ custId: 457 },
{ $set: { deliveryDate: ISODate( "2021-03-01" ) } }
)
db.shipping.updateOne(
{ custId: 458 },
{ $set: { deliveryDate: ISODate( "2021-03-02" ) } }
)

Você deseja encontrar remessas atrasadas. Use $dateAdd em um estágio $match para criar um filtro que corresponda a documentos em uma faixa de datas definido por um ponto de partida ($purchaseDate) e um período dado por $dateAdd.

db.shipping.aggregate(
[
{
$match:
{
$expr:
{
$gt:
[ "$deliveryDate",
{
$dateAdd:
{
startDate: "$purchaseDate",
unit: "day",
amount: 5
}
}
]
}
}
},
{
$project:
{
_id: 0,
custId: 1,
purchased:
{
$dateToString:
{
format: "%Y-%m-%d",
date: "$purchaseDate"
}
},
delivery:
{
$dateToString:
{
format: "%Y-%m-%d",
date: "$deliveryDate"
}
}
}
}
]
)

O estágio $match utiliza $gt e $dateAdd em uma expressão ($expr) para comparar o deliveryDate real com uma data esperada. Os documentos com datas de entrega superiores a 5 dias após o purchaseDate são passados para a etapa $project.

O estágio $project utiliza a expressão $dateToString para converter as datas em um formato mais legível. Sem a conversão, o MongoDB retorna a data no formato ISODate e assume um fuso horário UTC.

Neste exemplo, apenas um registro é retornado:

{ "custId" : 456, "purchased" : "2020-12-31", "delivery" : "2021-01-10" }

Todas as datas são armazenadas internamente no horário UTC. Quando um timezone é especificado, o $dateAdd utiliza a hora local para executar os cálculos. Os resultados são exibidos em UTC.

Você tem clientes em vários fusos horários e deseja ver o efeito que o horário de verão pode ter em seus períodos de faturamento se você faturar por day ou por hour.

Criar esta coleção de tempos de conexão:

db.billing.insertMany(
[
{
location: "America/New_York",
login: ISODate("2021-03-13T10:00:00-0500"),
logout: ISODate("2021-03-14T18:00:00-0500")
},
{
location: "America/Mexico_City",
login: ISODate("2021-03-13T10:00:00-00:00"),
logout: ISODate("2021-03-14T08:00:00-0500")
}
]
)

Primeiro, adicione 1 dia e, em seguida, adicione 24 horas às datas login em cada documento.

db.billing.aggregate(
[
{
$project:
{
_id: 0,
location: 1,
start:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date: "$login"
}
},
days:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "day",
amount: 1,
timezone: "$location"
}
}
}
},
hours:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "hour",
amount: 24,
timezone: "$location"
}
}
}
},
startTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date: "$login",
timezone: "$location"
}
},
daysTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "day",
amount: 1,
timezone: "$location"
}
},
timezone: "$location"
}
},
hoursTZInfo:
{
$dateToString:
{
format: "%Y-%m-%d %H:%M",
date:
{
$dateAdd:
{
startDate: "$login",
unit: "hour",
amount: 24,
timezone: "$location"
}
},
timezone: "$location"
}
},
}
}
]
).pretty()

A expressão $dateToString reformata a saída para legibilidade. Os resultados são resumidos aqui:

Campo
New York
Cidade do México
Iniciar
2021-03-13 15:00
2021-03-13 10:00
Início, TZ Info
2021-03-13 10:00
2021-03-13 04:00
1 dia
2021-03-14 14:00
2021-03-14 10:00
1 dia, informações TZ
2021-03-14 10:00
2021-03-14 04:00
24 horas
2021-03-14 15:00
2021-03-14 10:00
24 horas, informações sobre TZ
2021-03-14 11:00
2021-03-14 04:00

O gráfico destaca vários pontos:

  • As datas não formatadas retornam em UTC. O $login para Nova York é UTC -5, no entanto, as linhas start, days e hours exibem o tempo em UTC.

  • de março é o início do DST em Nova York, mas não no México. O tempo calculado é ajustado quando um local muda para DST e cruza de um day para o outro.

  • O horário de verão modifica o comprimento do day, não do hour. Não há alteração de DST para hours. Só há um ajuste para o horário de verão quando a medida unit é day ou maior e o cálculo ultrapassa uma mudança de relógio no timezone especificado.

Dica

Veja também:

Voltar

$covarianceSamp