En MongoDB, el $dateFromString
El operador de canalización de agregación convierte una cadena de fecha/hora en un objeto de fecha.
Ejemplo
Supongamos que tenemos una colección llamada foo
con los siguientes documentos:
{ "_id" : 1, "bar" : "2020-12-31T23:30:25.123" } { "_id" : 2, "bar" : "2020-12-31" } { "_id" : 3, "bar" : "2020-12-31T23:30" }
Todos los documentos contienen una cadena de fecha/hora.
Podemos ejecutar el siguiente código para devolver un objeto de fecha desde la bar
campos en esos 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 las cadenas de fecha/hora se han convertido en un objeto de fecha.
También cambié el nombre del campo de bar
a date
.
Especifique un formato
Puede proporcionar un format
opcional argumento para especificar el formato de la cadena de fecha/hora que se proporciona. La especificación de formato puede ser cualquier cadena literal, que contenga 0 o más especificadores de formato.
El format
El parámetro está disponible desde MongoDB versión 4.0.
El formato predeterminado es %Y-%m-%dT%H:%M:%S.%LZ
, que es lo que usa el ejemplo anterior.
Supongamos que insertamos el siguiente documento en nuestra colección:
{ "_id" : 4, "bar" : "07/08/2020" }
En este caso, la fecha podría ser el día 7 del mes 8 o el día 8 del mes 7, según la configuración regional que se utilice.
Podemos usar una especificación de formato para especificar exactamente cuál debería ser.
Ejemplo:
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") }
En este caso, especificamos que es el día 8 del mes 7.
Aquí está de nuevo, pero esta vez intercambiamos el día y el mes.
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") }
Esta vez se interpreta como el día 7 del mes 8.
Ver MongoDB $dateFromString
Especificadores de formato para obtener una lista de especificadores de formato válidos.
Formato de fecha de semana ISO
Hay algunos especificadores de formato que le permiten especificar fechas utilizando el formato ISO 8601.
En particular, puede utilizar:
Especificador de formato | Salida |
---|---|
%G | Año en formato ISO 8601 |
%u | Número del día de la semana en formato ISO 8601 (1 lunes, 7 domingo) |
%V | Semana del año en formato ISO 8601 |
Supongamos que tenemos un documento que se ve así:
{ "_id" : 5, "bar" : "7-8-2020" }
Podríamos interpretar esa fecha como el día 7 de la semana ISO, seguida de la semana ISO 8 del año, seguida del año.
Así:
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") }
Especifique una zona horaria
Puede especificar una zona horaria para usar con $dateFromString
operador.
La zona horaria se puede especificar utilizando el identificador de zona horaria de Olson (por ejemplo, "Europe/London"
, "GMT"
) o el desplazamiento UTC (por ejemplo, "+02:30"
, "-1030"
).
Identificador de zona horaria de Olson
Aquí hay un ejemplo que genera la cadena de fecha en tres zonas horarias diferentes, cada una con los ID de zona horaria de 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") }
Desplazamiento UTC
Aquí hay un ejemplo que usa el desplazamiento 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") }
Si usa la timezone
parámetro, la cadena de fecha no se puede agregar con una Z para indicar la hora zulú (zona horaria UTC). Por ejemplo, la cadena de fecha no puede ser 2020-12-31T23:30:25.123Z
cuando se utiliza el parámetro de zona horaria.
Además, no incluya información de zona horaria en la cadena de fecha cuando utilice el parámetro de zona horaria.
El onNull
Parámetro
El onNull
El parámetro se puede usar para especificar qué devolver si la fecha es nula o no existe.
El valor proporcionado a onNull
el parámetro puede ser cualquier expresión válida.
Supongamos que tenemos un documento como este:
{ "_id" : 6, "bar" : null }
Podríamos usar onNull
de la siguiente manera:
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" }
En este caso, la fecha era null
y entonces el documento de salida incluye la cadena que proporcioné para onNull
parámetro.
El onError
Parámetro
Opcionalmente, puede usar el onError
parámetro para proporcionar una expresión a la salida en caso de que ocurra un error.
Supongamos que nuestra colección contiene el siguiente documento:
{ "_id" : 7, "bar" : "21st Dec, 2030" }
Aunque hay una fecha en la bar
campo, no es una cadena de fecha/hora válida y, por lo tanto, causará un error si usamos dateFromString
para intentar convertirlo en un objeto de fecha.
Ejemplo de error:
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
Ese es un error que parece desagradable.
Podemos usar el onError
parámetro para que se vea mejor:
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" }
Ver como el onNull
y onError
Los parámetros nos permiten devolver los documentos reales, nos permiten devolver varios documentos, sin preocuparnos de que un documento incorrecto detenga toda la operación.
Ejemplo:
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" }