No MongoDB, o
$dateFromString
operador de pipeline de agregação converte uma string de data/hora em um objeto de data. Exemplo
Suponha que tenhamos uma coleção chamada
foo
com os seguintes documentos:{ "_id" : 1, "bar" : "2020-12-31T23:30:25.123" } { "_id" : 2, "bar" : "2020-12-31" } { "_id" : 3, "bar" : "2020-12-31T23:30" }
Todos os documentos contêm uma string de data/hora.
Podemos executar o seguinte código para retornar um objeto de data da
bar
campos nesses documentos. db.foo.aggregate([
{
$project: {
date: {
$dateFromString: {
dateString: '$bar'
}
}
}
}
])
Resultado:
{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") } { "_id" : 2, "date" : ISODate("2020-12-31T00:00:00Z") } { "_id" : 3, "date" : ISODate("2020-12-31T23:30:00Z") }
Todas as strings de data/hora foram convertidas em um objeto de data.
Também alterei o nome do campo de
bar
para date
. Especifique um formato
Você pode fornecer um
format
opcional argumento para especificar o formato da string de data/hora que está sendo fornecida. A especificação de formato pode ser qualquer literal de string, contendo 0 ou mais especificadores de formato. O
format
O parâmetro está disponível no MongoDB versão 4.0. O formato padrão é
%Y-%m-%dT%H:%M:%S.%LZ
, que é o que o exemplo anterior usa. Suponha que inserimos o seguinte documento em nossa coleção:
{ "_id" : 4, "bar" : "07/08/2020" }
Nesse caso, a data pode ser o 7º dia do 8º mês ou o 8º dia do 7º mês, dependendo da localidade que está sendo usada.
Podemos usar uma especificação de formato para especificar exatamente qual deve ser.
Exemplo:
db.foo.aggregate([
{ $match: { _id: 4 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%m/%d/%Y"
}
}
}
}
])
Resultado:
{ "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") }
Nesse caso, especificamos que é o 8º dia do 7º mês.
Aqui está novamente, mas desta vez trocamos o dia e o mês.
db.foo.aggregate([
{ $match: { _id: 4 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%d/%m/%Y"
}
}
}
}
])
Resultado:
{ "_id" : 4, "date" : ISODate("2020-08-07T00:00:00Z") }
Desta vez é interpretado como o 7º dia do 8º mês.
Veja MongoDB
$dateFromString
Especificadores de formato para obter uma lista de especificadores de formato válidos. Formato de data de semana ISO
Existem alguns especificadores de formato que permitem especificar datas usando o formato ISO 8601.
Em particular, você pode usar:
Especificador de formato | Saída |
---|---|
%G | Ano no formato ISO 8601 |
%u | Número do dia da semana no formato ISO 8601 (1-segunda-feira, 7-domingo) |
%V | Semana do ano no formato ISO 8601 |
Suponha que temos um documento que se parece com isso:
{ "_id" : 5, "bar" : "7-8-2020" }
Poderíamos interpretar essa data como sendo o 7º dia da semana ISO, seguido pela 8ª semana ISO do ano, seguido do ano.
Assim:
db.foo.aggregate([
{ $match: { _id: 5 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
format: "%u-%V-%G"
}
}
}
}
])
Resultado:
{ "_id" : 5, "date" : ISODate("2020-02-23T00:00:00Z") }
Especificar um fuso horário
Você pode especificar um fuso horário para usar com o
$dateFromString
operador. O fuso horário pode ser especificado usando o identificador de fuso horário Olson (por exemplo,
"Europe/London"
, "GMT"
) ou o deslocamento UTC (por exemplo, "+02:30"
, "-1030"
). Identificador de fuso horário Olson
Aqui está um exemplo que gera a string de data em três fusos horários diferentes, cada um usando os IDs de fuso horário Olson:
db.foo.aggregate([
{ $match: { _id: 1 } },
{
$project: {
utc: {
$dateFromString: {
dateString: '$bar',
timezone: "UTC"
}
},
honolulu: {
$dateFromString: {
dateString: '$bar',
timezone: "Pacific/Honolulu"
}
},
auckland: {
$dateFromString: {
dateString: '$bar',
timezone: "Pacific/Auckland"
}
}
}
}
]).pretty()
Resultado:
{ "_id" : 1, "utc" : ISODate("2020-12-31T23:30:25.123Z"), "honolulu" : ISODate("2021-01-01T09:30:25.123Z"), "auckland" : ISODate("2020-12-31T10:30:25.123Z") }
Deslocamento UTC
Aqui está um exemplo que usa o deslocamento UTC.
db.foo.aggregate([
{ $match: { _id: 1 } },
{
$project: {
"date+00:00": {
$dateFromString: {
dateString: '$bar',
timezone: "+00:00"
}
},
"date-10:00": {
$dateFromString: {
dateString: '$bar',
timezone: "-10:00"
}
},
"date+12:00": {
$dateFromString: {
dateString: '$bar',
timezone: "+12:00"
}
}
}
}
]).pretty()
Resultado:
{ "_id" : 1, "date+00:00" : ISODate("2020-12-31T23:30:25.123Z"), "date-10:00" : ISODate("2021-01-01T09:30:25.123Z"), "date+12:00" : ISODate("2020-12-31T11:30:25.123Z") }
Se você usar o
timezone
parâmetro, a string de data não pode ser anexada com um Z para indicar a hora Zulu (fuso horário UTC). Por exemplo, a string de data não pode ser 2020-12-31T23:30:25.123Z
ao usar o parâmetro fuso horário. Além disso, não inclua informações de fuso horário na string de data ao usar o parâmetro timezone.
O onNull
Parâmetro
O
onNull
O parâmetro pode ser usado para especificar o que retornar se a data for nula ou não existir. O valor fornecido ao
onNull
parâmetro pode ser qualquer expressão válida. Suponha que temos um documento como este:
{ "_id" : 6, "bar" : null }
Poderíamos usar
onNull
Da seguinte maneira:db.foo.aggregate([
{ $match: { _id: 6 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onNull: "No valid date was supplied"
}
}
}
}
])
Resultado:
{ "_id" : 6, "date" : "No valid date was supplied" }
Nesse caso, a data era
null
e assim o documento de saída inclui a string que eu forneci para o onNull
parâmetro. O onError
Parâmetro
Opcionalmente, você pode usar o
onError
parâmetro para fornecer uma expressão para saída no caso de ocorrer um erro. Suponha que nossa coleção contenha o seguinte documento:
{ "_id" : 7, "bar" : "21st Dec, 2030" }
Mesmo que haja uma data na
bar
campo, não é uma string de data/hora válida e, portanto, causará um erro se usarmos dateFromString
para tentar convertê-lo em um objeto de data. Exemplo de erro:
db.foo.aggregate([
{ $match: { _id: 7 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar'
}
}
}
}
])
Resultado:
Error: command failed: { "ok" : 0, "errmsg" : "an incomplete date/time string has been found, with elements missing: \"21st Dec, 2030\"", "code" : 241, "codeName" : "ConversionFailure" } : aggregate failed : [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/assert.js:18:14 [email protected]/mongo/shell/assert.js:618:17 [email protected]/mongo/shell/assert.js:708:16 [email protected]/mongo/shell/db.js:266:5 [email protected]/mongo/shell/collection.js:1046:12 @(shell):1:1
Isso é um erro de aparência desagradável.
Podemos usar o
onError
parâmetro para torná-lo mais bonito:db.foo.aggregate([
{ $match: { _id: 7 } },
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onError: "An error occurred while parsing the date string"
}
}
}
}
])
Resultado:
{ "_id" : 7, "date" : "An error occurred while parsing the date string" }
Vendo como o
onNull
e onError
parâmetros nos permitem retornar os documentos reais, eles nos permitem retornar vários documentos, sem nos preocupar com um documento ruim parando toda a operação. Exemplo:
db.foo.aggregate([
{
$project: {
date: {
$dateFromString: {
dateString: '$bar',
onNull: "The date was either empty or null",
onError: "An error occurred while parsing the date string"
}
}
}
}
])
Resultado:
{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") } { "_id" : 2, "date" : ISODate("2020-12-31T00:00:00Z") } { "_id" : 3, "date" : ISODate("2020-12-31T23:30:00Z") } { "_id" : 4, "date" : ISODate("2020-07-08T00:00:00Z") } { "_id" : 5, "date" : ISODate("2020-08-07T00:00:00Z") } { "_id" : 6, "date" : "The date was either empty or null" } { "_id" : 7, "date" : "An error occurred while parsing the date string" }