MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

MongoDB $dateFromParts


No MongoDB, o $dateFromParts operador de pipeline de agregação constrói e retorna um objeto Date das partes constituintes da data.

Você fornece cada parte da data como um campo separado.

Você pode especificar seus campos de data constituintes no formato de data de semana ISO, se necessário.

Exemplo


Suponha que tenhamos uma coleção chamada dateParts com o seguinte documento:
{
	"_id" : 1,
	"year" : 2020,
	"month" : 12,
	"day" : 31,
	"hour" : 23,
	"minute" : 30,
	"second" : 25,
	"millisecond" : 123
}

O documento contém um campo diferente para cada parte da data.

Podemos executar o código a seguir para retornar um objeto de data dos campos desses 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 as partes de data/hora foram convertidas em um único objeto de data.

Fusos horários


Você pode usar o timezone campo para especificar um fuso horário.

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 usa IDs de fuso horário Olson para gerar três datas diferentes de um único documento, com base em três fusos horários 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")
}

Deslocamento UTC


Aqui está um exemplo que usa o deslocamento 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 data de semana ISO


As partes da data podem ser especificadas usando o formato ISO 8601, se necessário.

Em particular, você pode usar:
Especificador de formato Saída
isoWeekYear Ano no formato ISO 8601. Este campo é obrigatório se não estiver usando year (e year é necessário se não estiver usando isoWeekYear ).
isoWeek Semana do ano no formato ISO 8601. Só pode ser usado com isoWeekYear .
isoDayOfWeek Dia da semana (1-segunda-feira, 7-domingo). Só pode ser usado com isoWeekYear .

Suponha que inserimos um segundo documento que se parece com isso:
{
	"_id" : 2,
	"isoWeekYear" : 2021,
	"isoWeek" : 32,
	"isoDayOfWeek" : 7,
	"hour" : 23,
	"minute" : 30,
	"second" : 25,
	"millisecond" : 123,
	"timezone" : "UTC"
}

Podemos ver que ele usa isoWeekYear , isoWeek e isoDayOfWeek em vez de year , month e day (que é o que o primeiro documento usa).

Podemos usar o seguinte código para construir um objeto Date deste 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 fora do intervalo


A partir do MongoDB 4.4, o intervalo de valores com suporte para year e isoWeekYear é 1-9999 . Nas versões anteriores, o limite inferior para esses valores era 0 e o intervalo de valores suportado era 0-9999 .

A partir do MongoDB 4.0, se o valor especificado para campos diferentes de year , isoWeekYear e timezone estiver fora do intervalo válido, o $dateFromParts operador carrega ou subtrai a diferença de outras partes da data para calcular a data.

Valores acima do intervalo


Suponha que adicionamos o seguinte documento à nossa coleção:
{
	"_id" : 3,
	"year" : 2020,
	"month" : 14,
	"day" : 65,
	"hour" : 48,
	"minute" : 130,
	"second" : 625,
	"millisecond" : 123
}

Muitos dos campos de data e hora neste documento são maiores que seus respectivos intervalos válidos.

Vamos executar o seguinte comando para convertê-lo em um objeto Date:
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 as partes de data no objeto Date resultante são diferentes de suas respectivas partes de data no documento. Isso ocorre porque $dateFromParts recalculou a data para contabilizar os valores de parte da data que excederam seu intervalo normal.

Valores abaixo do intervalo


Suponha que adicionamos o seguinte documento à nossa coleção:
{
	"_id" : 4,
	"year" : 2020,
	"month" : 0,
	"day" : 0,
	"hour" : 0,
	"minute" : 0,
	"second" : 0,
	"millisecond" : 0
}

Muitos dos campos de data e hora neste documento são inferiores a seus respectivos intervalos válidos.

Vamos executar o seguinte comando para convertê-lo em um objeto Date:
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") }