sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB $dateFromParts

En MongoDB, el $dateFromParts El operador de canalización de agregación construye y devuelve un objeto Fecha a partir de las partes constituyentes de la fecha.

Usted proporciona cada parte de la fecha como un campo separado.

Puede especificar sus campos de fecha constituyentes en formato de fecha de semana ISO si es necesario.

Ejemplo

Supongamos que tenemos una colección llamada dateParts con el siguiente documento:

{
	"_id" : 1,
	"year" : 2020,
	"month" : 12,
	"day" : 31,
	"hour" : 23,
	"minute" : 30,
	"second" : 25,
	"millisecond" : 123
}

El documento contiene un campo diferente para cada parte de la fecha.

Podemos ejecutar el siguiente código para devolver un objeto de fecha de los campos en esos documentos.

db.dateParts.aggregate([
{
   $project: {
      date: {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond"
         }
      }
   }
}])

Resultado:

{ "_id" : 1, "date" : ISODate("2020-12-31T23:30:25.123Z") }

Todas las partes de fecha/hora se han convertido en un solo objeto de fecha.

Zonas horarias

Puedes usar la timezone campo para especificar una zona horaria.

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

Este es un ejemplo que utiliza ID de zona horaria de Olson para generar tres fechas diferentes de un solo documento, en función de tres zonas horarias diferentes.

db.dateParts.aggregate([
{
   $project: {
      dateUTC: {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond",
            "timezone": "Pacific/Auckland"
         }
      },
      dateHonolulu: {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond",
            "timezone": "Pacific/Honolulu"
         }
      },
      dateAuckland: {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond",
            "timezone": "Pacific/Auckland"
         }
      }
   }
}]).pretty()

Resultado:

{
	"_id" : 1,
	"dateUTC" : ISODate("2020-12-31T10:30:25.123Z"),
	"dateHonolulu" : ISODate("2021-01-01T09:30:25.123Z"),
	"dateAuckland" : ISODate("2020-12-31T10:30:25.123Z")
}

Desplazamiento UTC

Aquí hay un ejemplo que usa el desplazamiento UTC.

db.dateParts.aggregate([
{
   $project: {
      "date+00:00": {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond",
            "timezone": "+00:00"
         }
      },
      "date-10:00": {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond",
            "timezone": "-10:00"
         }
      },
      "date+12:00": {
         $dateFromParts: {
            "year": "$year", 
            "month": "$month", 
            "day": "$day", 
            "hour": "$hour", 
            "minute": "$minute", 
            "second": "$second", 
            "millisecond": "$millisecond",
            "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")
}

Formato de fecha de semana ISO

Las partes de la fecha se pueden especificar utilizando el formato ISO 8601 si es necesario.

En particular, puede utilizar:

Especificador de formato Salida
isoWeekYear Año en formato ISO 8601. Este campo es obligatorio si no se usa year (y year se requiere si no se usa isoWeekYear ).
isoWeek Semana del año en formato ISO 8601. Solo se puede usar con isoWeekYear .
isoDayOfWeek Día de la semana (1-lunes, 7-domingo). Solo se puede usar con isoWeekYear .

Supongamos que insertamos un segundo documento que se parece a esto:

{
	"_id" : 2,
	"isoWeekYear" : 2021,
	"isoWeek" : 32,
	"isoDayOfWeek" : 7,
	"hour" : 23,
	"minute" : 30,
	"second" : 25,
	"millisecond" : 123,
	"timezone" : "UTC"
}

Podemos ver que usa isoWeekYear , isoWeek y isoDayOfWeek en lugar de year , month y day (que es lo que usa el primer documento).

Podemos usar el siguiente código para construir un objeto Fecha a partir de este documento:

db.dateParts.aggregate([
  { $match: { _id: 2} },
  {
    $project: {
        date: {
          $dateFromParts: {
              "isoWeekYear": "$isoWeekYear", 
              "isoWeek": "$isoWeek", 
              "isoDayOfWeek": "$isoDayOfWeek", 
              "hour": "$hour", 
              "minute": "$minute", 
              "second": "$second", 
              "millisecond": "$millisecond", 
              "timezone": "$timezone"
          }
        }
    }
  }
])

Resultado:

{ "_id" : 2, "date" : ISODate("2021-08-15T23:30:25.123Z") } 

Campos fuera de rango

A partir de MongoDB 4.4, el rango de valores admitido para year y isoWeekYear es 1-9999 . En versiones anteriores, el límite inferior de estos valores era 0 y el rango de valores admitido fue 0-9999 .

A partir de MongoDB 4.0, si el valor especificado para campos que no sean year , isoWeekYear y timezone está fuera del rango válido, el $dateFromParts el operador lleva o resta la diferencia de otras partes de la fecha para calcular la fecha.

Valores superiores al rango

Supongamos que agregamos el siguiente documento a nuestra colección:

{
	"_id" : 3,
	"year" : 2020,
	"month" : 14,
	"day" : 65,
	"hour" : 48,
	"minute" : 130,
	"second" : 625,
	"millisecond" : 123
}

Muchos de los campos de fecha y hora en este documento son más altos que sus respectivos rangos válidos.

Ejecutemos el siguiente comando para convertirlo en un objeto Fecha:

db.dateParts.aggregate([
  { $match: { _id: 3} },
  {
    $project: {
        date: {
          $dateFromParts: {
              "year": "$year", 
              "month": "$month", 
              "day": "$day", 
              "hour": "$hour", 
              "minute": "$minute", 
              "second": "$second", 
              "millisecond": "$millisecond"
          }
        }
    }
  }
])

Resultado:

{ "_id" : 3, "date" : ISODate("2021-04-08T02:20:25.123Z") }

Podemos ver que las partes de fecha en el objeto Fecha resultante son diferentes a sus respectivas partes de fecha en el documento. Esto se debe a que $dateFromParts recalculó la fecha para tener en cuenta los valores parciales de fecha que excedieron su rango normal.

Valores inferiores al rango

Supongamos que agregamos el siguiente documento a nuestra colección:

{
	"_id" : 4,
	"year" : 2020,
	"month" : 0,
	"day" : 0,
	"hour" : 0,
	"minute" : 0,
	"second" : 0,
	"millisecond" : 0
}

Muchos de los campos de fecha y hora en este documento son más bajos que sus respectivos rangos válidos.

Ejecutemos el siguiente comando para convertirlo en un objeto Fecha:

db.dateParts.aggregate([
  { $match: { _id: 4} },
  {
    $project: {
        date: {
          $dateFromParts: {
              "year": "$year", 
              "month": "$month", 
              "day": "$day", 
              "hour": "$hour", 
              "minute": "$minute", 
              "second": "$second", 
              "millisecond": "$millisecond"
          }
        }
    }
  }
])

Resultado:

{ "_id" : 4, "date" : ISODate("2019-11-30T00:00:00Z") }